一对一实体框架代码优先使用复合键映射

时间:2013-11-26 15:46:33

标签: c# entity-framework ef-code-first

是否可以在已定义的实体属性上创建一对一的关系?我有以下实体:

public class Asset
{
    public int AssetId { get; set; }
    public int OwningCustomerId { get; set; }
    public virtual Customer OwningCustomer { get; set; }
}

public class CustomerAsset
{
    public int CustomerId { get; set; } // Primary key 0
    public int AssetId { get; set; }    // Primary key 1
    public int CustomerAssetStatusId { get; set; }
    public string Name { get; set; }

    public virtual Customer Customer { get; set; }
    public virtual Asset Asset { get; set; }
}

CustomerAsset表示资产的各种所有权状态。虽然在此表中可以多次存在相同的AssetId,但只有一个实例,其中CustomerAssetStatusId = 1.为了快速访问资产的当前所有者,我还在Asset表中维护OwningCustomerId。

我想从Asset到CustomerAsset有一个名为OwningCustomerAsset的导航属性。这是一对一的关系。不幸的是,我不知道如何定义它,因为外键字段已在Asset中定义。通常,我会在Asset:

上创建这样的关系
HasRequired(e => e.OwningCustomerAsset).WithRequiredDependent().Map(m => m.MapKey("OwningCustomerId", "AssetId"));

当然,这会导致以下错误:“类型中的每个属性名称必须是唯一的。属性名称'OwningCustomerId'已经定义。”

如何告诉EF OwningCustomerId / AssetId是CustomerAsset的外键?

2 个答案:

答案 0 :(得分:0)

如果您可以修改架构,我建议将资产所有权作为资产本身的属性而不是客户资产关系。拥有从AssetCustomer的不可为空的FK字段(例如Owner_CustomerID)会强制执行“仅限一个所有者”约束,并且可以从CustomerAsset.Asset.Owner轻松加载所有者(或无论你选择什么名字)。此架构更改将大大简化您的查询。

此外,这将允许您向引用所有拥有资产的Customer添加导航属性; Customer.OwnedAssets,例如

更新

还可以使用新的Asset.OwningCustomerAsset字段通过复合FK AssetCustomerAsset添加导航属性Owner_CustomerID(或任何您想要的)( AssetId, Owner_CustomerId )结果导航属性

答案 1 :(得分:0)

由于我走到这条路的另一端需要一个导航属性(我不再需要了),我一直坚持一对一的心态。以下是我想要的:

HasRequired(e => e.OwningCustomerAsset).WithMany().HasForeignKey(e =>  new { e.OwningCustomerId, e.AssetId });