繁体   English   中英

实体框架6外键问题

[英]Entity Framework 6 Foreign Key Issue

我已经与用户进行了设置

public class User{
     [Key]
     public int UserId {get;set;}

     public virtual ICollection<Sub_User> SubUser {get;set;}
     //Other
}

然后是另一种基于主要用户的用户。

public class Sub_User{
     [Key]
     public int Sub_User_ID {get;set;}

     int UserID {get;set;} //Foreign Key to User in DB
     public virtual User User {get;set;}
     //Other
}

除非我进行如下设置,否则我无法使其正常工作。

modelBuilder.Entity<User>()
            .HasMany(e => e.Sub_Users)
            .WithRequired(e => e.User)

这是这样的。 但是我遇到的问题是为什么我需要拥有子用户的ICollection 我尝试过使它像

     public virtual Sub_User SubUser {get;set;}

然后更改其在模型构建器中的工作方式,但无法正常工作,并且出现错误。

主要用户应该只有1个Sub_User,因此我感到奇怪的是,唯一的在线解决方案以及使它正常运行的唯一方法是使用集合。

以下是实现您要寻找的一些选项。 如果Sub_User与有效/现有User绑定,并且User最多具有一个Sub_User 在选项3中使用[required]注释似乎是最干净的,并且不需要任何Fluent API配置。

选项1)

Sub_Userint UserId属性添加[ForeignKey]批注

public class User {
     [Key]
     public int UserId { get; set; }

     public virtual Sub_User SubUser { get; set; }
}

public class Sub_User{
     [Key]
     public int Sub_User_ID { get; set; }

     [ForeignKey("User")]
     public int UserID { get; set; }

     public virtual User User { get; set; }
}

选项2)

Fluent API(已删除[ForeignKey]UserId ):

public class User {
     [Key]
     public int UserId { get; set; }

     public virtual Sub_User SubUser { get; set; }
}

public class Sub_User{
     [Key]
     public int Sub_User_ID { get; set; }

     public virtual User User { get; set; }
}

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{   
    // Configure UserId as FK for Sub_User
    modelBuilder.Entity<User>()
                .HasOptional(u => u.SubUser) 
                .WithRequired(su => su.User);
}

选项3)

您也可以在没有Fluent API的情况下,尝试在Sub_UserUser User属性上设置[required]数据注释,并删除int UserId属性和[ForeignKey]注释:

public class Sub_User{
    [Key]
    public int Sub_User_ID { get; set; }

    [Required]
    public virtual User User { get; set; }
}

更新:

我创建了一个示例MVC 5 EF 6项目,并使用[Required]标签,Code First从这些类中生成了以下表格:

C#

public class User
{
    [Key]
    public int UserId { get; set; }

    public string Name { get; set; }

    public virtual Sub_User SubUser { get; set;}
}

public class Sub_User
{
    [Key]
    public int Sub_User_ID { get; set; }

    public string Name { get; set; }

    [Required]
    public virtual User User { get; set; }

}

SQL:

CREATE TABLE [dbo].[User] (
    [UserId] INT            IDENTITY (1, 1) NOT NULL,
    [Name]   NVARCHAR (MAX) NULL,
    CONSTRAINT [PK_dbo.User] PRIMARY KEY CLUSTERED ([UserId] ASC)
);

CREATE TABLE [dbo].[Sub_User] (
    [Sub_User_ID] INT            NOT NULL,
    [Name]        NVARCHAR (MAX) NULL,
    CONSTRAINT [PK_dbo.Sub_User] PRIMARY KEY CLUSTERED ([Sub_User_ID] ASC),
    CONSTRAINT [FK_dbo.Sub_User_dbo.User_Sub_User_ID] FOREIGN KEY ([Sub_User_ID]) REFERENCES [dbo].[User] ([UserId]) );


GO CREATE NONCLUSTERED INDEX [IX_Sub_User_ID]
    ON [dbo].[Sub_User]([Sub_User_ID] ASC);

我能够同时使用Sub_User和没有Sub_User来保存User元素,因为Sub_User SubUser对于User对象是可选的:

var users = new List<User>()
{
    new User { Name = "Foo", SubUser = new Sub_User { Name = "Bar" } },
    new User { Name = "FooBar" }
};

users.ForEach(u => context.Users.Add(u));

context.SaveChanges();

如果您尝试添加没有有效/现有UserSub_User ,则该User将失败,例如,以下操作将失败:

var subUsers = new List<Sub_User>()
{
    new Sub_User { Name= "Unicorn" }
};

subUsers.ForEach(su => context.SubUsers.Add(su));

context.SaveChanges();

示例上下文:

public class SampleContext : DbContext {

    public SampleContext() : base("SampleContext") {}

    public DbSet<User> Users { get; set; }
    public DbSet<Sub_User> SubUsers { get; set; }
}

希望有帮助!

就像公开Sub_User.UserID一样简单。 否则,可能会发生以下情况:

public int UserID;

[NotMapped]
public User User
{
    get
    {
        return _context.Users.where(u=>u.UserID==UserID).FirstOrDefault();
    }
    set
    {
        UserID = value.UserID;
    }

}

暂无
暂无

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

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