2016-11-15 2 views
3

Update:C# LINQ к SQL объединения нескольких строк

Существует еще одна таблица называется Местоположение специальных знаков. Он содержит сохраненный идентификатор местоположения и специальные знаки. Необходимо сделать результат в переменной SpecialSignsLocation и получить следующее:

public IEnumerable<KeyValuePair<int, int>> SpecialSignsLocation = new List<KeyValuePair<int, int>>(); 

    //json result 
    ... 
     SpecialSigns: { 
        BodyType: [1, 2], 
        Hair: [3, 1, 2], 
        SpecialSignsLocation: [[1,2], [3,5], [4,1]] 
       } 

    ... 

    //query 
    SpecialSignsLocation = entity.persons_signs_location 
          .Where(c => c.PersonId == persons.Id) 
          .Select(s => new { s.Location, s.Sign}) 
          .ToDictionary(l => l.Location, l => l.Sign) 

Я написал запрос, но я пролетает исключение:

Expression LINQ к Entities не распознает метод системы. Collections.Generic.Dictionary

Есть 3 стола: Персоны, ПерсоныSignsHair, ПерсоныSignsBodyType. Один человек может иметь много специальных знаков:

Picture

public List<object> GetPerson(int id) 
{ 
    var query = (from persons in entity.persons where persons.Id.Equals(id) 
       join signs_body_type in entity.persons_signs_body_type 
       on persons.Id equals signs_body_type.PersonId into _signs_body_type 
         from signs_body_type in _signs_body_type.DefaultIfEmpty() 

       join signs_hair in entity.persons_signs_hair 
       on persons.Id equals signs_hair.PersonId into _signs_hair 
         from signs_hair in _signs_hair.DefaultIfEmpty() 

       select new Person 
         { 
          PersonName = persons.PersonName, 
          PersonLastName = persons.PersonLastName, 
          PersonPatronymic = persons.PersonPatronymic, 
          SpecialSigns = new PersonSpecialSigns() 
          { 
           BodyType = _signs_body_type.Select(c => c.PersonBodyType), 
           Hair = _signs_hair.Select(h => h.PersonHair) 
          } 
       }); 

    return query.ToList<object>(); 
} 

После запроса, результат преобразуется в формат JSON. Выход, я ожидаю следующий результат:

[ 
    { 
     SpecialSigns: { 
      BodyType: [1, 2], 
      Hair: [3, 1, 2] 
     }, 

     PersonName: "Aaa", 
     PersonLastName: "Bbb", 
     PersonPatronymic: "Ccc", 

    }, 
] 

Вместо этого результат дублируется 6 раз.

[ 
    { 
     SpecialSigns: { 
      BodyType: [1, 2], 
      Hair: [3, 1, 2] 
     }, 

     PersonName: "Aaa", 
     PersonLastName: "Bbb", 
     PersonPatronymic: "Ccc", 

    }, 
{ 
     SpecialSigns: { 
      BodyType: [1, 2], 
      Hair: [3, 1, 2] 
     }, 

     PersonName: "Aaa", 
     PersonLastName: "Bbb", 
     PersonPatronymic: "Ccc" 

    }, 
{ 
     SpecialSigns: { 
      BodyType: [1, 2], 
      Hair: [3, 1, 2] 
     }, 

     PersonName: "Aaa", 
     PersonLastName: "Bbb", 
     PersonPatronymic: "Ccc" 

    }, 
{ 
     SpecialSigns: { 
      BodyType: [1, 2], 
      Hair: [3, 1, 2] 
     }, 

     PersonName: "Aaa", 
     PersonLastName: "Bbb", 
     PersonPatronymic: "Ccc" 

    }, 
{ 
     SpecialSigns: { 
      BodyType: [1, 2], 
      Hair: [3, 1, 2] 
     }, 

     PersonName: "Aaa", 
     PersonLastName: "Bbb", 
     PersonPatronymic: "Ccc" 

    }, 
{ 
     SpecialSigns: { 
      BodyType: [1, 2], 
      Hair: [3, 1, 2] 
     }, 

     PersonName: "Aaa", 
     PersonLastName: "Bbb", 
     PersonPatronymic: "Ccc" 

    } 
] 

Вопрос: Как объединить специальные идентификаторы, и привести их в массив?

+0

Пожалуйста, включите результат, который вы получите также. – wdosanjos

+1

@wdosanjos Я думаю, что он был достаточно ясным: * результат дублируется 6 раз * – meJustAndrew

+0

Если вам нужна только одна запись, вы можете сделать 'FirstOrDefault()' –

ответ

1

Пожалуйста, попробуйте следующее. join's вызывают декартовую продукцию.

public List<object> GetPerson(int id) 
{ 
    var query = (from persons in entity.persons where persons.Id.Equals(id) 

       select new Person 
        { 
         PersonName = persons.PersonName, 
         PersonLastName = persons.PersonLastName, 
         PersonPatronymic = persons.PersonPatronymic, 
         SpecialSigns = new PersonSpecialSigns() 
         { 
          BodyType = entity.persons_signs_body_type 
               .Where(c => c.PersonId == persons.Id) 
               .Select(c => c.PersonBodyType), 
          Hair = entity.persons_signs_hair 
              .Where(c => c.PersonId == persons.Id) 
              .Select(h => h.PersonHair) 
         } 
       }); 

    return query.ToList<object>(); 
} 
+0

Спасибо, это работает! – murash

1

Я собираюсь сделать снимок. Но, я почти уверен, что если вы используете DefaultIfEmpty(), вы принесите Left Outer Join к вашим результатам. Вот почему вы, вероятно, дублируете все. Опустим это, и вы будете иметь ваше внутреннее соединение (то, что я думаю, что вы ищете)

var query = from persons in entity.persons where persons.Id == id 
      select new Person 
      { 
       PersonName = persons.PersonName, 
       PersonLastName = persons.PersonLastName, 
       PersonPatronymic = persons.PersonPatronymic, 
       SpecialSigns = new PersonSpecialSigns() 
       { 
        BodyType = entity.persons_signs_body_type 
            .Where(i => i.PersonId == id) 
            .Select(i => i.PersonBodyType), 
        Hair = entity.persons_signs_hair 
           .Where(i => i.PersonId == id) 
           .Select(i => i.PersonHair) 
       } 
      }; 

Кроме того, в качестве рекомендации, я хотел бы использовать FirstOrDefault(), чтобы проверить, если человек существует первый, а затем я бы заполнить класс.

var personData = entity.persons.FirstOrDefault(i = i.Id == id); 

if(personData != null) 
{ 
    var person = new Person 
    { 
     PersonName = personData.PersonName, 
     PersonLastName = personData.PersonLastName, 
     PersonPatronymic = personData.PersonPatronymic, 
     SpecialSigns = new PersonSpecialSigns() 
     { 
      BodyType = entity.persons_signs_body_type 
          .Where(i => i.PersonId == personData.Id) 
          .Select(i => i.PersonBodyType), 
      Hair = entity.persons_signs_hair 
         .Where(i => i.PersonId == personData.Id) 
         .Select(i => i.PersonHair) 
     } 
    }; 
    //continue with the code 
} 
+0

Спасибо, это работает! – murash

+0

Сладкий! Я рад, что это сработало –

1

Короткая рука linq здесь должна работать нормально.

public List<object> GetPerson(int id) 
{ 
    var query = entity.persons.First(x=> x.Id == id).Select(x=> new Person 
       { 
        PersonName = x.PersonName, 
        PersonLastName = x.PersonLastName, 
        PersonPatronymic = x.PersonPatronymic, 
        SpecialSigns = new PersonSpecialSigns       
        { 
         BodyType = entity.persons_signs_body_type 
             .Where(y => y.PersonId == x.Id) 
             .Select(y => y.PersonBodyType), 
         Hair = entity.persons_signs_hair 
             .Where(y => y.PersonId == x.Id) 
             .Select(y => y.PersonHair) 
        } 
       }); 

    return query.ToList<object>(); 
} 
1

Предполагая, что вы используете Entity Framework и ваши лица похож на них:

Person.cs

public int Id { get; set; } 
public string PersonName { get; set; } 
public string PersonLastName { get; set; } 
public string PersonPatronymic { get; set; } 

public ICollection<PersonsSignsHair> PersonsSignsHair { get; set; } 
public ICollection<PersonsSignsBodyType> PersonsSignsBodyType { get; set; } 

PersonsSignsHair.cs

public int Id { get; set; } 
public int PersonId { get; set; } 
public string PersonHair { get; set; } 

PersonsSignsBodyType.CS

public int Id { get; set; } 
public int PersonId { get; set; } 
public string PersonBodyType { get; set; } 

И у вас есть контекст так:

public DbSet<PersonsSignsHair> PersonsSignsHair { get; set; } 
public DbSet<PersonsSignsBodyType> PersonsSignsBodyType { get; set; } 
public DbSet<Person> People { get; set; } 

Вы можете загрузить Человек со связанными лицами, как этот

entity.People.Where(x => x.Id == id).Include(y => y.PersonsSignsHair).Include(z => z.PersonsSignsBodyType).FirstOrDefault(); 
Смежные вопросы