2017-10-19 50 views
0

我试图检索使用LINQ的加入,与在实体框架表中的特定类,其中条件如下:获取特定对象后,加入使用LINQ

   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(); 

我想“结果”对象作为Person对象返回。在上面的例子中,我需要创建一个新的Person对象并添加来自结果的字段。

可能吗?我尝试了一些方法,并使用一些样本和研究,但没有任何替代方案为我工作。

谢谢!

更新1

好吧,一些读数之后,最好的我发现这样做是创造我的人对象DTO类,并在我的funcion返回这个DTO类如下方式:

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类?

我正在使用一张表,但一个例如有2​​0个表的程序将迫使我有20个实体类和20个实体DTO类!作为一个初学者,我认为这种工作方式有点混乱或无意义,使传统的方式(使用数据读取器,命令和连接)。即使更加官僚化,也不需要“重复”的对象。

有人可以提供这个答案吗?

更新2

按照要求:因为我不笏一个匿名类型在我的函数返回时,我试图回到实体类(人),但我这样做的时候,我得到以下错误我的应用程序执行:

“实体或复杂类型'Models.Person'不能在LINQ to Entities查询中构造。”

所以解决方案是创建一个DTO类(或视图模型类,无论)。

+1

为什么不'选择了',而不是因为你没有使用任何字段从''b选择新...' '在你的结果? –

+0

你正在创建一个匿名类型 – derloopkat

+0

你做的是正确的...你只需要选择人而不是 –

回答

1

如果您的数据库中有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(); 
+0

它是一个返回Person对象的函数,但是我可以将一个匿名类型返回给Person对象。我已经试过了。 –

+0

我不认为我理解你遇到的问题。有没有错误信息? –

+0

结果的类型应该是这个代码的Person。除非你的上下文定义有些怪异。 –

0

你应该能够做到

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类是可访问的工作,它的位置是进口的,它具有公共干将/ setter具有与上面相匹配的属性。

如果您仍然遇到问题,请尝试将您的班级定义包括在内,并且您可能会看到任何错误。

编辑:根据你所看到的错误,我猜你试图只选择这个实体上的一些属性。英孚实际上不会让你这样做。您可以选择整个实体(通过不指定属性并只选择a),或者您可以创建一个自定义DTO,您可以像上面那样映射到该实体。

EF不喜欢不完整的映射,因为它使状态混淆未来的模型修改。 See this answer here.所以,如果你想避免加载整个实体,去定制的DTO路线。

+0

我假设您可能试图选择与EF对象类型不同的类。如果它与上下文中定义的相同,请使用oerkelens答案。 –

+0

是的,Person返回对象是由Database First Entity Framework方法生成的同一Person对象。但是当我尝试建议的代码时,我得到这个错误:“实体或复杂类型'Models.Person'不能在LINQ to Entities查询中构建。” –

+0

@Lucas,答案已更新。 –

0

你的代码是正确的!去这个解决方案,因为它具有最小修改 只选择人

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(); 
+1

尝试了这一点,但在程序执行过程中出现以下错误:“实体或复杂类型'Models.Person'无法在LINQ to Entities查询中构建。”我应该为此创建一个DTO类吗? –

+0

所以你不是已经有一个类人?你需要为每个可重用的实体创建类...这是很好的编程练习 –

+0

谁地狱downvoted它...什么:( –