Linq-创建包含集合的新对象

时间:2019-02-25 12:05:42

标签: entity-framework linq collections

我正在尝试使用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 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 :(得分:0)

这不是LINQ的真正问题。它更多关于对象初始化。第一条规则(对我而言)如果对象具有集合,则它永远不能为null。它可以为空,但不能为空。 (另一个问题是,是否应该设置collection属性,但这是另一回事了。)

to_representation

然后您可以像这样初始化对象:

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

有关对象初始化的更多信息,请访问Microsoft

答案 1 :(得分:0)

您写道:

  

我目前的情况是,一个地址存储在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中Address的属性将是AlternativeAddress中的列。

如果您没有使用类地址来确保MainAddress的结构与AlternativeAddresses完全相同,则必须执行Select。

这是实体框架检测表以及表,主键和外键之间的关系所需了解的所有信息。仅当您需要其他标识符时,才需要属性或流利的API。

  

要求。给定输入参数personId,请给我(带有其所有地址的人)(某些属性)。

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,
        ...
    }),