C# 使用LINQ在连接后获取特定对象
我正在尝试使用linq for join和where条件检索实体框架中与表相关的特定类,条件如下:C# 使用LINQ在连接后获取特定对象,c#,entity-framework,linq,C#,Entity Framework,Linq,我正在尝试使用linq for join和where条件检索实体框架中与表相关的特定类,条件如下: var result = (from a in db.Persons join b in db.Person_IDs on a.PersonId equals b.PersonId where b.FaceId == faceId
var result = (from a in db.Persons
join b in db.Person_IDs on a.PersonId equals b.PersonId
where b.FaceId == faceId
select new
{
PersonId = a.PersonId,
Name = a.Name,
Address = a.Address,
Picture = a.Picture,
City = a.City,
Estate = a.Estate,
Phone = a.Phone,
CellPhone = a.CellPhone,
BlackList = a.BlackList
}
).FirstOrDefault();
PersonDTO result = (from a in db.Persons
join b in db.Person_IDs on a.PersonId equals b.PersonId
where b.FaceId == faceId
select new PersonDTO
{
PersonId = a.PersonId,
Name = a.Name,
Address = a.Address,
Picture = a.Picture,
City = a.City,
Estate = a.Estate,
Phone = a.Phone,
CellPhone = a.CellPhone,
BlackList = a.BlackList
}
).FirstOrDefault();
db.Dispose();
return result;
我希望“result”对象作为Person对象返回。在上面的例子中,我需要创建一个新的Person对象并添加来自结果的字段
可能吗?我尝试了一些方法,使用了一些样本和研究,但没有一种方法对我有效
谢谢
更新1
好的,经过一些阅读,我发现最好的方法是为Person对象创建一个DTO类,并在函数中返回这个DTO类,如下所示:
var result = (from a in db.Persons
join b in db.Person_IDs on a.PersonId equals b.PersonId
where b.FaceId == faceId
select new
{
PersonId = a.PersonId,
Name = a.Name,
Address = a.Address,
Picture = a.Picture,
City = a.City,
Estate = a.Estate,
Phone = a.Phone,
CellPhone = a.CellPhone,
BlackList = a.BlackList
}
).FirstOrDefault();
PersonDTO result = (from a in db.Persons
join b in db.Person_IDs on a.PersonId equals b.PersonId
where b.FaceId == faceId
select new PersonDTO
{
PersonId = a.PersonId,
Name = a.Name,
Address = a.Address,
Picture = a.Picture,
City = a.City,
Estate = a.Estate,
Phone = a.Phone,
CellPhone = a.CellPhone,
BlackList = a.BlackList
}
).FirstOrDefault();
db.Dispose();
return result;
好吧,它工作得很好,但有一件事困扰着我:为什么要创建另一个与EF类相同的类?为什么EF类不能这样使用
我使用的是一个表,但是一个有20个表的程序会强迫我有20个实体类和20个实体DTO类
作为一个初学者,我认为这种工作方式有点杂乱无章或毫无意义,使传统的工作方式(使用数据读取器、命令和连接)。即使更加官僚化,它也不需要“重复”对象
有人能提供这个答案吗
更新2
按要求:由于我的函数中没有返回匿名类型,因此我尝试返回实体类(Person),但在执行此操作时,我在应用程序执行中遇到以下错误:
无法在LINQ to Entities查询中构造实体或复杂类型“Models.Person”。
因此,解决方案是创建一个DTO类(或viewmodel类,随便什么)。如果数据库中有
Person
对象,并且想要Person
对象,为什么要创建匿名类型
为什么不试试呢
var result = (from a in db.Persons
join b in db.Person_IDs on a.PersonId equals b.PersonId
where b.FaceId == faceId
select a).FirstOrDefault();
你应该能做到
var result = (from a in db.Persons
join b in db.Person_IDs on a.PersonId equals b.PersonId
where b.FaceId == faceId
select new Person
{
PersonId = a.PersonId,
Name = a.Name,
Address = a.Address,
Picture = a.Picture,
City = a.City,
Estate = a.Estate,
Phone = a.Phone,
CellPhone = a.CellPhone,
BlackList = a.BlackList
}).FirstOrDefault();
只要Person类是可访问的,它的位置是导入的,并且它有公共getter/setter,其属性与上面的匹配,这就应该可以工作
如果仍然存在问题,请尝试包含person的类定义以及可能看到的任何错误
编辑:根据您看到的错误,我猜您试图仅选择此实体上的某些属性。EF实际上不会让你这么做。您可以选择整个实体(不指定属性,只选择a
),也可以创建自定义DTO,您可以像上面那样映射到该DTO
EF不喜欢不完整的映射,因为它会使状态对将来的模型修改产生混淆。因此,如果您希望避免加载整个实体,请使用自定义DTO路线。您的代码是正确的!!选择此解决方案,因为它的修改量最小 只需选择个人
person result = (from a in db.Persons
join b in db.Person_IDs on a.PersonId equals
b.PersonId
where b.FaceId == faceId
select new person
{
PersonId = a.PersonId,
Name = a.Name,
Address = a.Address,
Picture = a.Picture,
City = a.City,
Estate = a.Estate,
Phone = a.Phone,
CellPhone = a.CellPhone,
BlackList = a.BlackList
}
).FirstOrDefault();
既然结果中没有使用
b
中的任何字段,为什么不选择a而不是select new…
,PersonID等??我在这里假设您可能试图选择与EF对象类型不同的类。如果它与您上下文中定义的相同,请使用oerkelens答案。是的,返回的Person对象是由Database First Entity Framework方法生成的同一Person对象。但是当我尝试建议的代码时,我得到了这样的错误:“实体或复杂类型‘Models.Person’不能在LINQ to Entities查询中构造。”这是一个返回Person对象的函数,但我可以向Person对象返回匿名类型。我已经试过了。我想我不明白你遇到的问题。是否有错误消息?result
的类型应为带有此代码的Person
。除非你的上下文定义有什么问题。@LucasNeves你可以返回一个匿名对象,很好。但是,如果可以直接从您的选择中选择并返回键入的人
,为什么要这样做呢?你试过了,怎么了?请编辑您的问题,添加必要的信息。尝试了此操作,但在程序执行过程中出现以下错误:“无法在LINQ to Entities查询中构造实体或复杂类型的“Models.Person”。“我是否应该为此创建DTO类?那么您是否已经有类Person??”????你需要为每个可重用的实体创建类…这是很好的编程实践,但是拥有实体类和dto类是一个很好的实践吗?在实体框架中没有…我们使用称为视图模型的东西,尽管它们在某些方面类似于dto。。但是尝试创建视图模型,而不是DTO