如何在Entity Framework Core 1.0.1原始查询中包含相关实体?

时间:2016-10-08 11:40:58

标签: mysql entity-framework asp.net-core dbcontext entity-framework-core

设定:

  • ASP .NET Core 1 Web API

  • MySQL服务器社区版5.7

  • 带有Pomelo MySQL驱动程序的实体框架核心1.0.1(3个独立的上下文,3个独立的数据库)。

上下文:MainContext(maindb),Module1Context(module1db),Module2Context(module2db)。

我想执行一个返回Posts列表的查询(来自Module1Context),但我需要按作者权限(来自MainContext,User实体)过滤它们。

所以,我想要做的是使用JOIN子句执行查询到不同的数据库表:

var results = await module1Ctx.Posts.FromSql("select * from `module1db`.`posts` as `p` inner join `maindb`.`users` as `u` on `p`.`AuthorId`=`u`.`Id` where <conditions here>").ToListAsync();

执行此操作时,我得到一个SQL异常,告诉我“Sequence包含多个元素”。如果我选择p。*,它将起作用,但我还需要提取用户数据。

Post实体包含对用户ID的引用(public long AuthorId {get; set;}),以及伪导航属性NotMapped,因为EF无法自动加入2个数据库。 我的第一个问题是 - 这是可能的吗?我有一种强烈的感觉,这会起作用,但我错过了一些小事。

如果这不起作用,我将使用DbContext的Connection来手动执行查询。如果我这样做,我如何将结果映射到帖子列表,包括用户数据?

1 个答案:

答案 0 :(得分:3)

  

序列包含多个元素

这会告诉您列不止一次出现。例如,如果您在两个表中都有“ModifiedDate”列,那么当您执行select *时,它会在结果集中显示两次(p.ModifiedDate一次,u.ModifiedDate一次。

除此之外,返回的列必须与模型完全匹配。模型中定义的属性不得丢失,这就是p.*将起作用的原因。

但是,除非您的Post模型确实定义了表示User表中值的字段,否则您无法返回它们,因为它必须与Post及其映射属性完全匹配。

特殊支持(将结果映射到任意模型,如视图模型)尚未在EntityFramework Core 1.0中实现,并且是roadmap for future versions上的一项功能。

来自EntityFramework核心路线图:

  

关键O / RM功能

     
      
  • ...
  •   
  • 非模型类型的原始SQL查询允许使用原始SQL查询来填充不属于模型的类型(通常用于非规范化视图模型数据)。
  •   

修改

同样来自EFCore documentation

  

限制

     

使用原始SQL查询时需要注意几个限制:

     
      
  • SQL查询只能用于返回属于模型的实体类型。我们的待办事项有一个增强功能,可以从原始SQL查询中返回特殊类型。
  •   
  • SQL查询必须返回实体类型的所有属性的数据。
  •   
  • 结果集中的列名必须与属性映射到的列名匹配。请注意,这与EF6.x不同,其中原始SQL查询忽略属性/列映射,结果集列名必须与属性名称匹配。
  •   
  • SQL查询不能包含相关数据。但是,在许多情况下,您可以使用Include运算符在查询之上进行组合以返回相关数据(请参阅包括相关数据)。
  •