Linq - Создать новый объект, который содержит коллекцию - PullRequest
0 голосов
/ 25 февраля 2019

Я пытаюсь получить данные из Entity Framework, используя linq для заполнения пользовательского объекта.Проблема в том, что объект содержит коллекцию списков, в которой у меня возникают проблемы с заполнением.

У меня есть следующее

public class Person
{
    public string FirstName { get; set; }
    public string ListName { get; set; }
    public IList<Address> ContactAddresses v{ get; set; }
}

public class Address
{
    public string FirstLine { get; set; }
    public string SecondLine { get; set; }
    public string Town { get; set; }
}

Я пытаюсь заполнить объект Person, но возникают проблемы с заполнением списка.адреса.Ситуация у меня в данный момент один адрес хранится в таблице Person, а рабочие и другие адреса хранятся в другом.Сейчас я только пытаюсь получить адрес, сохраненный в таблице Person.Ниже приведена моя попытка, но синтаксис не работает.

Person details = context.Person.Where(p => p.Id == id)
                 .Select(p => new Person)
                 {
                     FirstName = p.FirstName,
                     LastName = p.LastName,
                     ContactAddresses = new List<Address>()
                                        .add(new Address
                                             (
                                                 FirstLine = m.FirstLineAddress,
                                                 SecondLine = m.SecondLine,
                                                 Town = m.Town
                                             ))
                  }.FirstOrDefault();

ОБНОВЛЕНИЕ:

Я решил, как это сделать.Следующее linq - мое решение.

Person details = context.Person.Where(p => p.Id == id)
                 .Select(p => new Person)
                 {
                     FirstName = p.FirstName,
                     LastName = p.LastName,
                     ContactAddresses = (new List<Address>()
                                 {
                                     new Address()
                                     {
                                         FirstLine = p.FirstLine ,
                                         SecondLine = p.SecondLine,
                                         Town = p.Town
                                     }
                                 }).ToList(),
                  }.FirstOrDefault();

Ответы [ 2 ]

0 голосов
/ 25 февраля 2019

Вы писали:

Ситуация, в которой я на данный момент храню один адрес, сохраняется в таблице Person, а рабочие и другие адреса хранятся в другом.

Итак, у вас есть класс Person, у которого есть контактный адрес, а также набор из нуля или более альтернативных адресов.Это может быть отношение «один ко многим» или отношение «многие ко многим», для класса Person это на самом деле не имеет значения:

class Person
{
    public int Id {get; set;}
    public Address MainAddress {get; set;}
    ... // other properties

    // every Person has zero or more Alternative Addresses:
    public virtual ICollection<AlternativeAddress> AlternativeAddresses {get; set;}
}

class AlternativeAddress
{
    public int Id {get; set;}
    public Address Address {get; set;}
    ... // other properties

    // if this Address belongs to exactly one Person (one-to-many)
    public int PersonId {get; set;}
    public virtual Person Person {get; set;}

    // or if this address may be the address of several Persons (many-to-many)
    public virtual ICollection<Person> Persons {get; set;}
}

В каркасе сущностей столбцы таблицыпредставлены не виртуальными свойствами.Виртуальные свойства представляют отношения между таблицами (один ко многим, многие ко многим, ...)

Адрес - это класс.Поскольку я не объявил MainAddress виртуальным, свойства Address будут столбцами внутри Person.Аналогично, свойства адреса в AlternativeAddress будут столбцами внутри альтернативного адреса.

Если вы не использовали адрес класса, чтобы убедиться, что ваш главный адрес имеет точно такую ​​же структуру, что и альтернативные адреса,должен сделать выбор.

Это все, что должна знать структура сущностей, чтобы обнаружить ваши таблицы и отношения между таблицами, первичным и внешним ключами.Только если вам нужны разные идентификаторы, вам нужны атрибуты или свободный API.

Требование Учитывая входной параметр personId, дайте мне (некоторые свойства) Person со всеми его адресами.

var result = dbContext.Persons
    .Where(person => person.Id == personId)
    .Select(person => new
    {
        // select only the properties you plan to use:
        Id = person.Id,
        FirstName = person.FirstName,
        ...

        // For the contact Addresses, concat the MainAddress and the Alternative Addresses
        ContactAddresses = new Address[] {person.MainAddress}
        .Concat(person.AlternativeAddresses.Select(address => address.Address)

        // use a Select if you don't need all Address properties:
        .Select(address =>  new
        {
            Street = address.Street,
            City = address.City,
            PostCode = address.PostCode,
            ...
       });

Если классы Person и AlternativeAddress не имеют свойств адреса, вам нужно выбрать нужные свойства:

 ContactAddresses = 
     // Main Address
     new []
     {
          Street = person.Street,
            City = person.City,
            PostCode = person.PostCode,
            ...
    }
    .Concat(person.AlternativeAddresses.Select(address => new
    {
        Street = address.Street,
        City = address.City,
        PostCode = address.PostCode,
        ...
    }),
0 голосов
/ 25 февраля 2019

Это на самом деле не проблема LINQ.Это больше об инициализации объекта.Первое правило (для меня), если у объекта есть коллекция, он никогда не должен быть нулевым.Это может быть пустым, но никогда не нулевым.(Другой вопрос будет, если свойство коллекции должно быть установлено или нет, но это другая история.)

public class Person
{
    public string FirstName { get; set; }
    public string ListName { get; set; }
    public IList<Address> ContactAddresses { get; set; } = new List<Address>();
}

И тогда вы можете инициализировать объект следующим образом:

var person = new Person
{
    FirstName = "Foo",
    ListName = "Bar",
    ContactAddresses = { new Address { FirstLine = "A", SecondLine = "B", Town = "C" } }
};

Как видите, у контактных адресов есть инициализатор, который не использует new.Таким образом, список объектов будет добавлен в существующий список.

Если вы хотите заменить список вместо его изменения, вы также можете предоставить новый список:

var person = new Person
{
    FirstName = "Foo",
    ListName = "Bar",
    ContactAddresses = new List<Address> { new Address { FirstLine = "A", SecondLine = "B", Town = "C" } }
};

Подробнее оИнициализация объекта может быть найдена в Microsoft .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...