设定:
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来手动执行查询。如果我这样做,我如何将结果映射到帖子列表,包括用户数据?
答案 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查询来填充不属于模型的类型(通常用于非规范化视图模型数据)。
限制
使用原始SQL查询时需要注意几个限制:
- SQL查询只能用于返回属于模型的实体类型。我们的待办事项有一个增强功能,可以从原始SQL查询中返回特殊类型。
- SQL查询必须返回实体类型的所有属性的数据。
- 结果集中的列名必须与属性映射到的列名匹配。请注意,这与EF6.x不同,其中原始SQL查询忽略属性/列映射,结果集列名必须与属性名称匹配。
- SQL查询不能包含相关数据。但是,在许多情况下,您可以使用Include运算符在查询之上进行组合以返回相关数据(请参阅包括相关数据)。