Считывать повторяющиеся потоки данных из базы данных в бизнес-объекты и различать их с помощью LINQ

#c# #linq #duplicates #reshape

#c# #linq #дубликаты #изменить

Вопрос:

Это данные в моей таблице базы данных:

введите описание изображения здесь

Это мой бизнес-объект:

 public class Unit
    {
        public Unit()
        {
            MemberIdList = new List<String>();
        }

        public String UnitType { get; set; }
        public String UnitZoom { get; set; }
        public String MemberZoom { get; set; }

        public List<String> MemberIdList { get; set; }
    }
  

Извлекаются все данные из базы данных и помещаются в DataTable.

Теперь начинается преобразование Linq…

После того, как я верну список с 3 объектами Unit, содержащими эти данные:

введите описание изображения здесь

Теперь угадайте, как я перенес данные в 3 бизнес-объекта… именно это я и хотел бы знать. Подсказка может быть Distinct и IEqualityComparer для трех свойств… просто предположение…

Обновить

Вопрос обновлен:

Пожалуйста, прочтите комментарий в коде 🙂

 var groupedCollection = table.AsEnumerable()
                                    .GroupBy(row => new
                                    {
                                        UType = row.Field<string>("UnitType"),
                                        UZoom = row.Field<string>("UnitZoom"),
                                        MZoom = row.Field<string>("MemberZoom"),
                                        MOrder = row.Field<int>("MemberOrder"), 
  

// Я НЕ ХОЧУ, чтобы MemberOrder был в ключе Group, но позже я использую это свойство для упорядочивания по нему…
});

             var unitCollection = groupedCollection
                                .Select(g => new Unit 
                                {
                                    UnitType = g.Key.UType,
                                    UnitZoom = g.Key.UZoom,
                                    MemberZoom = g.Key.MZoom,                                   
                                    MemberIdList = g.Select(r => r.Field<string>("MemberId")).OrderBy(b => g.Key.MOrder).ToList(),
                                });

            List<Unit> units = unitCollection.ToList(); 
  

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

1. Вам следует разделить вашу таблицу на две, чтобы избежать одинаковых строк. Затем вы можете использовать Linq2SQL непосредственно против него и получить ту же структуру, что и в вашем бизнес-объекте

2. здесь ничего не могу изменить. Все как есть 😉

Ответ №1:

Вот как я бы это сделал:

 var values = TblMembers.ToList();

var lst = 
    (from m in values
    group m by new { m.UnitType, m.UnitZoom, m.MemberZoom } into g
    select new
    {
        g.Key.UnitType,
        g.Key.UnitZoom,
        g.Key.MemberZoom,
        MemberIdList = g.Select (x => x.MemberID).ToList()
    }).ToList();
  

Ответ №2:

Что-то вроде этого?

 DataTable dt = ...

var list = 
dt.AsEnumerable()
.GroupBy(r => new
{
    UType = r.Field<string>("UnitType"),
    UZoom = r.Field<string>("UnitZoom"),
    MZoom = r.Field<string>("MemberZoom")
})
.Select(g => new Unit 
{ 
    UnitType = g.Key.UType, 
    UnitZoom = g.Key.UZoom, 
    MemberZoom = g.Key.MZoom ,
    MemberIdList = g.Select(r => r.Field<string>("MemberId")).Distinct().ToList()
})
.ToList();
  

Редактировать:
вызов .Distinct() не является строго необходимым. Это позволяет избежать дублирования идентификаторов элементов, если они у вас могут быть, но это действительно зависит от того, что нужно OP.

ПРАВКА2:
(согласно последнему обновлению вопроса)

Вы близки к решению:

просто измените эту строку моего кода:

 MemberIdList = g.Select(r => r.Field<string>("MemberId")).ToList()
  

Для:

 MemberIdList = g.Select(r => r.Field<string>("MemberId")).OrderBy(r => r.Field<int>("MOrder")).ToList()
  

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

1. @digEmAll Не думаю, что Distinct() это необходимо

2. кстати.почему вы различаете MemberID? группировка понятна, но я бы предпочел выделить 3 свойства… но это работает, лол 😉

3. @Magnus ДА, поэтому я написал, что это нормально для понимания… Я просто запутался в distinct, и вы были правы, это работает без distinct. У меня просто проблема с пониманием того, как заполняется MemberIdList… Необходимо снова изучить . Выберите(…

4. @Magnus: извините за поздний ответ, но мое соединение прервалось … да, Distinct не является строго необходимым, но я добавил его на всякий случай, если он захочет удалить дублирующиеся идентификаторы участников, если таковые имеются… Я намеревался добавить примечание об этом, но до сих пор не мог подключиться…

5. @digEmAll извините за поздний ответ, но я забыл сортировку; P Просто думаю, что у меня все еще есть 5-й столбец в моей таблице под названием MemberOrder, который имеет тип integer. Например, оба типа элементов A имеют MemberOrder 0 и 1. Это означает, что способ / порядок записи / добавления идентификатора участника в MemberIdList определяется номером MemberOrder. Как я могу расширить существующий код, чтобы каждый идентификатор элемента добавлялся в определенном порядке в список элементов? Я обновил свой вопрос фрагментом кода, почему он не работает. Было бы неплохо, если бы вы могли мне помочь, спасибо.

Ответ №3:

 var result =
        from n in data
        group n by new { n.UnitType, n.UnitZoom, n.MemberZoom } into g
        select new Unit 
        { 
          UnitType = g.Key.UnitType, 
          UnitZoom = g.Key.UnitZoom, 
          MemberZoom = g.Key.MemberZoom , 
          MemberIdList = g.Select ( r => r.MemberId).ToList() 
        };