我在两个表之间的实体框架中设置关联时遇到问题,其中关联不包含所有主键值。
e.g。我有两个表(这是一个人为的例子,但它足以表示我无法改变的真实数据库)
------Items------ ---Orders----
----------------- -------------
* ItemId - * OrderId -
* EffectiveDate - - OrderDate -
- Name - - ItemId -
----------------- ------------- * denotes primary key field
理想情况下,我希望Orders上的属性指示在OrderDate中有效的Item,但我可以将Order上的关联与Item集合一起使用,然后在Order上创建一个readonly属性,选择正确的Item。
编辑:数据库和模型将是只读的,因此只读解决方案是可以的。
这在实体框架中是否可行? (甚至是LINQ to SQL?)
我相信可以使用NHibernate(任何人都可以确认吗?)但我一直在用实体框架打砖墙。到目前为止,我所管理的唯一解决方案是在Order的partial类中创建一个属性,该属性使用“hack”从顺序访问ObjectContext并直接查询context.Items集合
private IEnumerable<Item> Items
{
get
{
var ctx = this.GetContext();
return from i in ctx.Items where i.ItemId == this.ItemId select i;
}
}
public Item Item
{
get
{
return (from i in Items
where i.EffectiveDate <= this.OrderDate
orderby i.EffectiveDate ascending
select i).First();
}
}
有更好的解决方案吗?
答案 0 :(得分:2)
问题是您的数据库设计不正确且这些表之间没有关系 - Order
不能与Item
建立FK关系,因为它的FK不包含Item的PK的所有部分。在数据库中,可以通过在ItemId
表中的Item
上放置唯一索引来避免这种情况,但它会使您的复合PK冗余,并且它不能解决EF的问题,因为EF不支持唯一键。由于缺少联结表,因此无法映射多对多关系。
所以EF的答案是否定的。同样的答案将是linq-to-sql。
答案 1 :(得分:0)
您可以使用方法并将上下文作为参数,或者只是创建一个新的上下文(至少在LINQ to SQL中,这取决于您的最小惩罚),而不是获取上下文的“hack”用例,如果我的研究有效)。
但是,您正在尝试创建一个条件链接,因此您将不得不编写一个表示此条件的方法 - 框架基本上执行相同的操作(即选择FK列中具有ID的Item) 。我不确定这样做的问题是什么?
我也被你的ERD彻底弄糊涂了 - 似乎:
出于好奇,这是正确的吗?
根据您无法更改ERD的事实,您提到的方法可能是实现此目标的最佳方法(尽管您可能希望将Items
标记为IQueryable<Item>
)。< / p>