简体   繁体   English

带有组合键的一对一实体框架代码优先映射

[英]One-To-One Entity Framework Code-First Mapping With Composite Keys

Is it possible to create a one-to-one relationship on already defined entity properties? 是否可以在已定义的实体属性上创建一对一关系? I've got the following entities: 我有以下实体:

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 represents various states of ownership of an asset. CustomerAsset代表资产的各种所有权状态。 Although the same AssetId can exist multiple times in this table, there will only ever be one instance where CustomerAssetStatusId = 1. In order to have quick access to the asset's current owner, I also maintain OwningCustomerId in the Asset table. 尽管同一个AssetId可以在该表中多次存在,但是只有一个实例,其中CustomerAssetStatusId =1。为了快速访问资产的当前所有者,我还在Asset表中维护OwningCustomerId。

I would like to have a navigation property from Asset to CustomerAsset called OwningCustomerAsset. 我想要一个从资产到CustomerAsset的导航属性,称为OwningCustomerAsset。 This is a one-to-one relationship. 这是一对一的关系。 Unfortunately, I don't know how to define it since the foreign key fields are already defined in Asset. 不幸的是,我不知道如何定义它,因为外键字段已经在Asset中定义了。 Typically, I would create a relationship like this on Asset: 通常,我会在Asset上创建这样的关系:

HasRequired(e => e.OwningCustomerAsset).WithRequiredDependent().Map(m => m.MapKey("OwningCustomerId", "AssetId"));

Of course this results in the following error: "Each property name in a type must be unique. Property name 'OwningCustomerId' was already defined." 当然,这将导致以下错误:“类型中的每个属性名称都必须是唯一的。属性名称'OwningCustomerId'已经定义。”

How can I tell EF that OwningCustomerId/AssetId is the foreign key to CustomerAsset? 如何告诉EF OwningCustomerId / AssetId是CustomerAsset的外键?

If you can modify your schema, I suggest making asset ownership a property of the asset itself and not of the customer-asset relationship. 如果可以修改架构,建议将资产所有权设为资产本身的属性,而不是客户资产关系的属性。 Having a non-nullable FK field from Asset to Customer (eg Owner_CustomerID ) enforces the "one owner only" constraint and the owner can be easily loaded from CustomerAsset.Asset.Owner (or whatever you choose to name it). AssetCustomer拥有一个不可为空的FK字段(例如Owner_CustomerID )会强制实施“仅一个所有者”约束,并且可以轻松地从CustomerAsset.Asset.Owner (或您选择的命名对象)中加载所有者。 This schema change will greatly simplify your queries. 此架构更改将大大简化您的查询。

Furthermore, this will allow you to add a navigation property to Customer that references all owned assets; 此外,这将允许您向Customer添加引用所有拥有资产的导航属性; Customer.OwnedAssets , for example 例如, Customer.OwnedAssets

Update: 更新:

Also add navigation property Asset.OwningCustomerAsset (or whatever you wish) from Asset to CustomerAsset using the new Owner_CustomerID field by way of compound FK ( AssetId, Owner_CustomerId ) and resulting navigation property 还通过复合FK ( AssetId, Owner_CustomerId )和新的导航属性( AssetId, Owner_CustomerId )使用新的Owner_CustomerID字段将导航属性Asset.OwningCustomerAsset (或从AssetAssetCustomerAsset

Since I came down this road needing a navigation property on the other end (which I don't need anymore), I was stuck with the one-to-one mindset. 由于我沿着这条路的另一端需要导航属性(不再需要),因此我一直保持一对一的心态。 The following gets me what I want: 以下是我想要的东西:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM