Entity Framework - 代码优先 - 导航属性太多

Entity Framework - code first - Too many navigation properties

我首先使用 Entity Framework 代码创建了两个 table,我需要一些帮助...!

Tables

  1. AccountLinks,3 个复合键
  2. 访客,3个复合外键(?)

Table 概览

SQL 概览

如您所见,我的数据库中有很多我不需要的导航属性。

AccountLink 代码

public class AccountLink
    {
        public AccountLink()
        {
            AccountLinkPermissionAccountLinkID = new HashSet<AccountLinkPermission>();
            AccountLinkPermissionAccountOwnerID = new HashSet<AccountLinkPermission>();
            AccountLinkPermissionGuestID = new HashSet<AccountLinkPermission>();
        }

        public AccountLink(int accountOwnerID, int guestID, DateTime dateCreated, DateTime dateStart, DateTime dateExpires)
        {
            AccountLinkPermissionAccountLinkID = new HashSet<AccountLinkPermission>();
            AccountLinkPermissionAccountOwnerID = new HashSet<AccountLinkPermission>();
            AccountLinkPermissionGuestID = new HashSet<AccountLinkPermission>();
            this.AccountOwnerID = accountOwnerID;
            this.GuestID = guestID;
            this.DateCreated = dateCreated;
            this.DateStart = dateStart;
            this.DateExpires = dateExpires;
        }

        [Key, Column(Order = 0)]
        public int AccountLinkID { get; set; }
        [Key, Column(Order = 1)]
        public int AccountOwnerID { get; set; }
        [Key, Column(Order = 2)]
        public int GuestID { get; set; }

        public DateTime DateCreated { get; set; }
        public DateTime DateStart { get; set; }
        public DateTime DateExpires { get; set; }

        [ForeignKey("AccountOwnerID")]
        public virtual AccountOwner AccountOwner { get; set; }

        [ForeignKey("GuestID")]
        public virtual Guest Guest { get; set; }

        public virtual ICollection<AccountLinkPermission> AccountLinkPermissionAccountLinkID { get; set; }
        public virtual ICollection<AccountLinkPermission> AccountLinkPermissionAccountOwnerID { get; set; }
        public virtual ICollection<AccountLinkPermission> AccountLinkPermissionGuestID { get; set; }
    }

AccountLinkPermissions 代码

public class AccountLinkPermission
    {
        public AccountLinkPermission()
        {

        }

        public AccountLinkPermission(int accountLinkID, int accountOwnerID, int guestID, int permissionID)
        {
            this.AccountLinkID = accountLinkID;
            this.AccountOwnerID = accountOwnerID;
            this.GuestID = guestID;
            this.PermissionID = permissionID;
        }

        [Key, Column(Order = 0)]
        public int AccountLinkID { get; set; }
        [Key, Column(Order = 1)]
        public int AccountOwnerID { get; set; }
        [Key, Column(Order = 2)]
        public int GuestID { get; set; }
        [Key, Column(Order = 3)]
        public int PermissionID { get; set; }

        [InverseProperty("AccountLinkPermissionAccountLinkID")]
        public virtual AccountLink AccountLink { get; set; }

        [InverseProperty("AccountLinkPermissionAccountOwnerID")]
        public virtual AccountLink AccountLinkAccountOwner { get; set; }

        [InverseProperty("AccountLinkPermissionGuestID")]
        public virtual AccountLink AccountLinkGuest { get; set; }

        [ForeignKey("PermissionID")]
        public virtual Permission Permission { get; set; }
    }

我想要3个组合键的原因是因为我想防止重复。

为什么我使用 InverseProperty 而不是 ForeignKey

因为我使用链接到同一个 table 的多个外键,EF 无法按照惯例确定哪些导航属性属于一起。而不是使用 属性 [ForeignKey] 我必须使用 [InverseProperty] 它在关系的另一端定义导航 属性。

用户代码

public class User
    {
        public User()
        {
            UserRoles = new HashSet<UserRole>();
            AccountLinks = new HashSet<AccountLink>();
        }

        public User(string firstName, string lastName, string email,
            string password, string passwordSalt, int agreeUserAgreement)
        {
            UserRoles = new HashSet<UserRole>();
            AccountLinks = new HashSet<AccountLink>();

            this.FirstName = firstName ?? string.Empty;
            this.LastName = lastName ?? string.Empty;
            this.Email = email;
            this.DateRegistered = Helpers.TimeZoneExtension.GetCurrentDate();
            this.DateLastActive = Helpers.TimeZoneExtension.GetCurrentDate();
            this.Password = password;
            this.PasswordSalt = passwordSalt;
            this.IsDeleted = 0;
            this.AgreeUserAgreement = agreeUserAgreement;
        }

        [Key]
        public int UserID { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public string Email { get; set; }
        public DateTime DateRegistered { get; set; }
        public DateTime DateLastActive { get; set; }
        public string Password { get; set; }
        public string PasswordSalt { get; set; }

        public string DefaultIpAddress { get; set; }

        public int IsDeleted { get; set; }

        public int AgreeUserAgreement { get; set; }

        public string UserRolesToString { get; set; }

        public virtual ICollection<UserRole> UserRoles { get; set; }
        public virtual ICollection<AccountLink> AccountLinks { get; set; }
    }

AccountOwner 代码

public class AccountOwner : User
{
    public AccountOwner()
    {
        UserRoles = new HashSet<UserRole>();
        AccountLinks = new HashSet<AccountLink>();
    }

    public AccountOwner(string firstName, string lastName, string email,
        string password, string passwordSalt, int agreeUserAgreement)
    {
        UserRoles = new HashSet<UserRole>();
        AccountLinks = new HashSet<AccountLink>();

        this.FirstName = firstName ?? string.Empty;
        this.LastName = lastName ?? string.Empty;
        this.Email = email;
        this.DateRegistered = DateTime.UtcNow.AddHours(1);
        this.DateLastActive = DateTime.UtcNow.AddHours(1);
        this.Password = password;
        this.PasswordSalt = passwordSalt;
        this.IsDeleted = 0;
        this.AgreeUserAgreement = agreeUserAgreement;
    }

    public virtual AccountUsagePremium AccountUsagePremium { get; set; }

    public virtual UploadDirectlyUsagePremium UploadDirectlyUsagePremium { get; set; }

    public override ICollection<UserRole> UserRoles { get; set; }
    public override ICollection<AccountLink> AccountLinks { get; set; }
}

访客代码

public Guest()
{
    UserRoles = new HashSet<UserRole>();
    AccountLinks = new HashSet<AccountLink>();
}

public Guest(string firstName, string lastName, string email,
    string password, string passwordSalt, int agreeUserAgreement)
{
    UserRoles = new HashSet<UserRole>();
    AccountLinks = new HashSet<AccountLink>();

    this.FirstName = firstName ?? string.Empty;
    this.LastName = lastName ?? string.Empty;
    this.Email = email;
    this.DateRegistered = TimeZoneExtension.GetCurrentDate();
    this.DateLastActive = TimeZoneExtension.GetCurrentDate();
    this.Password = password;
    this.PasswordSalt = passwordSalt;
    this.IsDeleted = 0;
    this.AgreeUserAgreement = agreeUserAgreement;
}

public override ICollection<UserRole> UserRoles { get; set; }
public override ICollection<AccountLink> AccountLinks { get; set; }

我需要什么帮助

如何先使用代码删除数据库中的所有导航属性?我知道我在某个地方搞砸了,但这就是我所知道的:)

1 在 AccountLinks 中导航 属性,(User_UserID)

AccountLinkPermissions 中的 9 个导航属性

加分题

在 AccountLink table 中,我有三个组合键, AccountLinkID、AccountOwnerID 和 GuestID。是否可以在 AccountLinkID 上放置自动增量(身份种子)?我将如何首先在 EF 代码中执行此操作?

从 Guest 和 AccountOwner 中删除此 类:

public override ICollection<UserRole> UserRoles { get; set; }
public override ICollection<AccountLink> AccountLinks { get; set; }

创建模型时:

modelBuilder.Entity<User>().Ignore(t => t.AccountLinks); 
modelBuilder.Entity<User>().Ignore(t => t.UserRoles); 
modelBuilder.Entity<AccountOwner>().ToTable("AccountOwners"); 
modelBuilder.Entity<Guest>().ToTable("Guests"); 

实体:

public class AccountLink
{
    [Key, Column(Order = 0), DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int AccountLinkID { get; set; }

    [Key, Column(Order = 1)]    
    public int AccountOwnerID { get; set; }

    [Key, Column(Order = 2)]
    public int GuestID { get; set; }

    public DateTime DateCreated { get; set; }
    public DateTime DateStart { get; set; }
    public DateTime DateExpires { get; set; }

    [ForeignKey("AccountOwnerID")]
    public virtual AccountOwner AccountOwner { get; set; }

    [ForeignKey("GuestID")]
    public virtual Guest Guest { get; set; }

    public virtual ICollection<AccountLinkPermission> AccountLinkPermissions { get; set; }
}

public class AccountLinkPermission 
{
    [Key, ForeignKey("AccountLink"), Column(Order = 0)]
    public int AccountLinkID { get; set; }

    [Key, ForeignKey("AccountLink"), Column(Order = 1)]
    public int AccountOwnerID { get; set; }

    [Key, ForeignKey("AccountLink"), Column(Order = 2)]
    public int GuestID { get; set; }

    [Key, Column(Order = 3)]
    public int PermissionID { get; set; }

    public virtual AccountLink AccountLink { get; set; }

    public virtual Permission Permission { get; set; }
}