【发布时间】:2014-08-01 01:00:10
【问题描述】:
我在这里查看了类似的问题,但没有看到这个特定的场景。
使用EF 6 Code First,我有三个表,A、B和C。关系是A => B = 1:M,B=>C = 1:1
这个模式的最终结果是在 A 和 C 之间存在一个隐含的 1:M。
我不希望实体框架模型的消费者知道 B。理想情况下,他们将拥有从 A 到 C 的 1:M 导航属性(并且我希望能够通过 Web API 显示此实体模型和 OData 作为 IQueryable)
我怎么能这样做?
如果我将自定义 [NotMapped] 属性添加到 C 集合的 A 中,我无法在该属性的 getter 中填充 C,因为实体不知道其上下文。
任何人对如何实现 IQueryable 有任何想法,其中 A 具有到 C 的导航属性并且 B 被“抽象”不存在?
编辑
尝试将以下内容放入代码优先实体 A:
[NotMapped]
public ICollection<C> Cs
{
get { return this.Bs.Select(b => b.C) as ICollection<C>; }
}
但是得到了这个错误: 导航属性“C”不是类型“A”的声明属性。验证它没有被明确地从模型中排除,并且它是一个有效的导航属性。
谢谢。
【问题讨论】:
-
implicit 1:M between A and C.是什么意思?你为什么不想通过 B 从 A 到 C 呢? -
我正在使用无法更改的旧架构。但是我的服务的消费者不需要知道这些表之间连接的细节。他们真的只关心 A 和 C 之间的关系。实体框架应该能够给消费者一个可查询的实体模型,它隐藏了必须发生的连接的细节。如果我在做 Model-First,我可能会考虑为此使用 DefiningQuery。
-
如果你想得到一个包含所有C的单个A,你只需要添加带有
[NotMapped]属性的Cs属性然后选择查询,var a = db.As.Include(a => a.Bs.Select(b => b.C)).FirstOrDefault(a => a.Id == key);并填写Cs,@987654326 @ -
Yuliam,感谢您的询问。这绝对适用于模型的消费者,但如果我正确阅读您的代码,它仍然需要 EF 模型消费者了解 B。没有地方可以告诉 EF 当访问 C 属性时,它应该运行该查询来填充它。客户会这样做,对吗?
-
那么您所说的消费者是指使用 dbcontext(odata 控制器)的任何代码吗?不是那些访问 odata 服务 (
http://localhost/Products) 的?
标签: c# entity-framework