我正在尝试使用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();
答案 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,
...
}),