简体   繁体   English

实体框架代码优先,与继承的1:1关联

[英]Entity Framework Code First, 1:1 association with inheritance

I have an abstract class UserProfile , it has a subclass Tenant , so the relationship is 1:1 - one 'user' is one 'tenant'. 我有一个抽象类UserProfile ,它有一个Tenant子类,所以关系是1:1-一个'user'是一个'tenant'。

Is this the correct way to implement table-per-type inheritance, on a 1:1 basis? 这是在1:1基础上实现每个类型的表继承的正确方法吗?

[Table("UserProfile")]
public abstract class UserProfile
{
    [Key]
    [DatabaseGeneratedAttribute(DatabaseGeneratedOption.Identity)]
    public int UserId { get; set; }
    // ...
}

[Table("Tenant")]
public class Tenant : UserProfile
{
    public string PersonalDescription { get; set; }
    // ...

    // Navigation property on dependant end
    public virtual UserProfile UserProfile { get; set; }
}
  • Am I correct in placing the navigation property on the dependant end of the relationship? 我将导航属性放置在关系的从属端是否正确? Or does it matter what end it goes on? 还是到底要紧吗?

  • Would I need to also place a navigation property of type Tenant in UserProfile ? 我是否还需要在UserProfile放置Tenant类型的导航属性?

  • Finally, I read that it is worthwhile making every property in a model virtual to help EF with change tracking - is this necessary? 最后,我读到值得将模型中的每个属性virtual以帮助EF进行更改跟踪-这是否必要?

In a table-per-type scenario you do not need navigation properties. 在每种类型的方案中,您不需要导航属性。 Tenant does not contain a UserProfile, Tenant is a UserProfile. 租户不包含UserProfile,租户是UserProfile。

EF should be able to get the values of the Tenant fields from the Tenant table, and the fields inherited from UserProfile from the UserProfile table. EF应该能够从Tenant表中获取Tenant字段的值,并从UserProfile表中获取从UserProfile继承的字段。 Looks magical, but it works, at least for me :) 看起来很神奇,但它至少对我有用:)

As for the DbSets, if you need to directly use a Tenant collection, you could add a Tenants DbSet. 至于DbSets,如果需要直接使用一个Tenant集合,你可以添加一个Tenants DbSet。 That would enable you to do: 这将使您能够:

myContext.Tenants.Where(t => ... t.PersonalDescription ... t.UserId ...)

which is equivalent with the longer and less discoverable 相当于更长和更少被发现

myContext.UserProfiles.OfType<Tenant>.Where(t => ....)

My personal preference is not to use the declared DbSets at all, and use the Set<T>() method directly in a wrapping repository, that exposes methods like GetByKey , Update etc.., but that is a matter of taste. 我个人的喜好是根本不使用声明的DbSet,而直接在包装存储库中使用Set<T>()方法,该方法公开了诸如GetByKeyUpdate等之类的方法,但这只是一个问题。

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

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