与实体框架的非键关联

本文关键字:关联 实体 框架 | 更新日期: 2023-09-27 17:52:11

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

。我有两个表(这是一个人为的例子,但它足以表示我无法更改的真实数据库)

------Items------    ---Orders----
-----------------    -------------
* ItemId        -    * OrderId   -
* EffectiveDate -    - OrderDate -
- Name          -    - ItemId    -
-----------------    -------------    * denotes primary key field

理想情况下,我希望在Orders上有一个属性,指示在OrderDate有效的Item,但是我可以在Order上与Item集合建立关联,然后在Order上创建一个只读属性,选择正确的Item。

编辑:数据库和模型将是只读的,所以只读解决方案是可以的。

这在实体框架中是可能的吗?(甚至从LINQ到SQL?)

我相信使用NHibernate是可能的(有人能确认吗?)但是我一直在实体框架上碰壁。到目前为止,我管理的唯一解决方案是在Order的部分类中创建一个属性,该属性使用"hack"从Order访问ObjectContext并查询上下文。

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

有更好的解决方案吗?

与实体框架的非键关联

问题是你的数据库设计不正确,这些表之间没有关系- Order不能与Item有FK关系,因为它的FK不包含Item的PK的所有部分。在数据库中,这可以通过在Item表的ItemId上放置唯一索引来避免,但它使你的复合PK冗余,它不能解决EF的问题,因为EF不支持唯一键。也不能映射多对多关系,因为缺少连接表。

所以EF的答案是否定的。同样的答案也适用于linq-to-sql。

与其"破解"获取上下文,不如使用方法并将上下文作为参数,或者简单地创建一个新上下文(至少在LINQ to SQL中,这取决于您的用例以及我的研究是否有效)。

然而,你试图创建一个条件链接,所以你将不得不写一个方法表示这个条件-框架基本上是做同样的事情(即选择项目与ID在FK列)。我不太确定这样做有什么问题?

我也完全被你的ERD搞糊涂了——看起来好像:

  • 项目有相同的ID,但随着时间的推移不同的名称(我不会叫表'Item'在这种情况下)
  • 每个订单是一个项目
  • 您正在尝试找出订购时的商品名称。

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

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