实体框架6外键问题

时间:2017-02-06 21:48:20

标签: c# entity-framework entity-framework-6

我已经设置了用户

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,所以我觉得奇怪的是,在线唯一的解决方案是我能让它正常运行的唯一方法是使用集合。

2 个答案:

答案 0 :(得分:0)

以下是实现您所需要的一些选项。 Sub_User与有效/现有UserUser相关联的位置最多只有一个Sub_User。在选项3中使用[required]注释似乎是最干净的,不需要任何Fluent API配置。

选项1)

[ForeignKey]注释添加到int UserId的{​​{1}}属性

Sub_User

选项2)

Fluent API(删除了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; } } [ForeignKey]):

UserId

选项3)

您也可以在没有Fluent API的情况下尝试在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); } 的{​​{1}}属性上设置[required]数据注释,并删除User User属性和Sub_User注释:< / p>

int UserId

<强>更新

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

C#

[ForeignKey]

SQL:

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

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

我能够使用Sub_User和Sub_User保存User元素,因为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; } } 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 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(); ,则会失败,例如以下内容失败:

Sub_User

示例上下文:

User

希望这有帮助!

答案 1 :(得分:0)

可能就像将Sub_User.UserID公开一样简单。否则,这样的事情可能有用:

public int UserID;

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

}