Сравните 2 столбца в DataTable с 2 столбцами в List и создайте новый список с определенными критериями

#c# #linq

#c# #linq

Вопрос:

У меня есть DataTable

 public static DataTable SubProjects = new DataTable();

public static DataTable GetSubProjects
{
    get { return SubProjects; }
}
  

он поступает из базы данных, поэтому столбцы следующие

 select ProjectN,ProjectSubN,ProjectM
  

и список:

 public class SubProjectsList
{
    public string ProjectNumber { get; set; }
    public string SubProjectNumber { get; set; }
    public string SubProjectName { get; set; }
    public string ProjectManager { get; set; }
    public int ObjectID { get; set; }

    public SubProjectsList(string ProjectNumber, string SubProjectNumber, string SubProjectName, string ProjectManager, int ObjectID)
    {
        this.ProjectNumber = ProjectNumber;
        this.SubProjectNumber = SubProjectNumber;
        this.SubProjectName = SubProjectName;
        this.ProjectManager = ProjectManager;
        this.SubProjectNumber = SubProjectNumber;
        this.ObjectID = ObjectID;
    }
}

public static List<SubProjectsList> DeliverySubProjectList = new List<SubProjectsList>();
  

В конечном итоге я хотел бы получить все результаты в новом списке, где

 ProjectN   ProjectSubN (DataTable) = ProjectNumber   SubProjectNumber (List) amp;amp; 
ProjectM (DataTable) != ProjectManager (List)
  

В качестве выходных данных мне нужно получить ProjectNumber , SubProjectNumber ProjectM , ProjectManager , ProjectM . В основном мне нужно поймать ProjectManager и,, это не соответствует одному подпроекту. Я мог бы сделать это таким образом

 var SubProjectResult = SubProjects.AsEnumerable()
    .Where(x => DeliverySubProjectList.Any(y => 
    y.ProjectNumber.Trim()   y.SubProjectNumber == x.Field<string>("ProjectN").Trim()   x.Field<string>("ProjectSubN").Trim() amp;amp;
    !string.Equals(y.ProjectManager.Trim(), x.Field<string>("ProjectM").Trim(), StringComparison.CurrentCultureIgnoreCase)))
    .Select(x => new
    {
        ProjectN = x.Field<string>("ProjectN"),
        ProjectN = x.Field<string>("ProjectSubN"),
        ProjectM = x.Field<string>("ProjectM"),
        ProjectM = x.ProjectManager // This is not possible
    })
    .OrderBy(o => o.ProjectN).ToList();
  

но

 ProjectM = x.ProjectManager // This is not possible
  

неверно и не компилируется. Поэтому я не могу получить ProjectManager из списка, где ProjectN ProjectSubN (DataTable) = ProjectNumber SubProjectNumber (List) совпадают, но ProjectManager не соответствует. Нужно ли сначала объединить DataTable и List вместе? Я пробовал это

 var myList1 = SubProjects.AsEnumerable().Concat(DeliverySubProjectList).ToList();
  

но выдает ошибку

Описание кода серьезности Ошибка состояния подавления строки файла проекта CS1929 ‘EnumerableRowCollection’ не содержит определения для ‘Concat’ и запрашивается перегрузка наилучшего метода расширения ‘.Для объединения (IQueryable, IEnumerable)’ требуется приемник типа ‘IQueryable’

Ответ №1:

Я думаю, это должно дать вам то, что вы ищете. Возможно, вам потребуется добавить дополнительные проверки null, и я также не очень уверен в том, как вы хотите добавить строковые значения из списка и таблицы данных:

 public class ResultModel
        {
            public string ProjectNumber { get; set; }
            public string SubProjectNumber { get; set; }
            public string ProjectM { get; set; }
            public string ProjectManager { get; set; }
        }

...
...
static void Main(string[] args)
        {
            List<SubProjectsList> DeliverySubProjectList = // populate list
            DataTable SubProjects = // populate datatable
            List<ResultModel> results = GetResults(DeliverySubProjectList, SubProjects).ToList();
        }

        private static IEnumerable<ResultModel> GetResults(List<SubProjectsList> DeliverySubProjectList, DataTable SubProjects)
        {
            return SubProjects.AsEnumerable().Select(row =>
            {
                var listItem = DeliverySubProjectList.FirstOrDefault(item =>
                {
                    return item.ProjectNumber   item.SubProjectNumber == row["ProjectN"].ToString()   row["ProjectSubN "].ToString()
                        amp;amp; !item.ProjectManager.Equals(row["ProjectM"].ToString());

                });

                if (listItem != null)
                {
                    return new ResultModel
                    {
                        ProjectNumber = row["ProjectN"].ToString(),
                        SubProjectNumber = listItem.SubProjectNumber,
                        ProjectM = row["ProjectM"].ToString(),
                        ProjectManager = listItem.ProjectManager
                    };
                }
                else
                {
                    return null;
                }
            })
            .Where(res => res != null);
        }
  

Комментарии:

1. Спасибо вам за это! Похоже, это может решить мою проблему, но можете ли вы также добавить пример использования. Я не совсем уверен, как реализовать этот метод для создания списка? List<(string ProjectNumber, string SubProjectNumber, string ProjectM, string ProjectManager)> SubProjectNumberList = new List<(string ProjectNumber, string SubProjectNumber, string ProjectM, string ProjectManager)>(); SubProjectNumberList = NewMethod(DeliverySubProjectList, SubProjects); ?