与实体框架的非键控关联

时间:2011-04-21 01:59:43

标签: c# linq nhibernate entity-framework linq-to-sql

我在两个表之间的实体框架中设置关联时遇到问题,其中关联不包含所有主键值。

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

有更好的解决方案吗?

2 个答案:

答案 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彻底弄糊涂了 - 似乎:

  • 项目具有相同的ID,但随着时间的推移会有不同的名称(在这种情况下,我不会将表格称为“项目”)
  • 每个订单适用于一个项目
  • 您正在尝试计算订单时商品的名称。

出于好奇,这是正确的吗?

根据您无法更改ERD的事实,您提到的方法可能是实现此目标的最佳方法(尽管您可能希望将Items标记为IQueryable<Item>)。< / p>