实体框架代码第一 - FOREIGN KEY约束问题 [英] Entity Framework Code first - FOREIGN KEY constraint problem

查看:180
本文介绍了实体框架代码第一 - FOREIGN KEY约束问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是新任的EF代码第一校长,目前不知道该怎么做..我有2个POCO课程。

  public class Problem 
{
public int ProblemID {get;组; }
public int UserID {get;组; }
public int CategoryID {get;组; }
public int RatingID {get;组; }

public string标题{get;组; }
public string描述{get;组; }
public double Latitude {get;组; }
public double Longitude {get;组; }
public int State {get;组; }
public DateTime CreatedOn {get;组; }

public virtual Rating Rating {get;组; }
public virtual Category Category {get;组; }
public virtual User User {get;组; }

public virtual ICollection< Picture>图片{get;组; }
public virtual ICollection< Comment>评论{get;组;
}

  public class User 
{
public int UserID {get;组; }
public int RoleID {get;组; }

public string Name {get;组; }
public string Surname {get;组; }
public string Email {get;组; }
public string Password {get;组; }
public string SocialHandle {get;组; }
public DateTime RegisteredOn {get;组; }

public virtual角色角色{get;组; }

public virtual ICollection< Point>积分{get;组; }
public virtual ICollection<问题>问题{get;组; }
public virtual ICollection< Comment>评论{get;组;
}

我的数据库创建是确定的,但是当我尝试初始化一些数据它使用自定义初始化程序,我正在得到以下错误:


介绍FOREIGN KEY约束'$ _ $'可能导致循环或多个级联路径。指定ON
DELETE NO ACTION或ON UPDATE NO ACTION,或修改其他FOREIGN KEY
约束。

无法创建约束。查看以前的错误。


这是我的初始化程序:

 $ {code> protected override void Seed(CleanStreets context)
{
var adminRole = new Role {Name =Administrator,RoleID = 0};
var moderatorRole = new Role {Name =Moderator,RoleID = 1};
var userRole = new Role {Name =User,RoleID = 2};

context.Roles.Add(adminRole);
context.Roles.Add(userRole);
context.Roles.Add(moderatorRole);

var admin = new User {Name =admin,Surname =admin,Role = adminRole,Email =fake@fake.com,Password =,RegisteredOn = DateTime.Now ,SocialHandle = null};
var user = new User {Name =user,Surname =user,Role = userRole,Email =fake@fake2.com,Password =,RegisteredOn = DateTime.Now,SocialHandle = null };

context.Users.Add(admin);
context.Users.Add(user);

var categoryOne = new Category {Title =Komunalni problemi,CategoryID = 0};
var categoryTwo = new Category {Title =Ostali problemi,CategoryID = 1};

context.Categories.Add(categoryOne);
context.Categories.Add(categoryTwo);

var problem = new问题{Category = categoryOne,Title =Prvi testni问题,描述=Ovo je testni opis,纬度= 45.5,经度= 15.5,状态= 0,CreatedOn = DateTime .Now,User = user};

context.Problems.Add(problem);

base.Seed(context);
}

我做错了什么?谢谢你提前!

解决方案

这将是因为评论。默认情况下,EF使用级联删除参考。在你的情况下,级联删除将从用户 - >问题,用户 - >注释创建,但也从问题 - >注释创建。如果删除用户级联到相同的注释记录可以来自问题用户。这在SQL Server中是不允许的。每个记录只能通过单个级联删除路径访问。



为避免这种情况,您必须使用流畅的映射来在一个关系上转换级联删除(您必须选择哪一个)。用户 - >评论的例子

  public class上下文:DbContext 
{
public DbSet< User>用户{get;组; }
public DbSet< Comment>评论{get;组; }
public DbSet<问题>问题{get;组;

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity< User>()
.HasMany(u => u.Comments)
.HasRequired(c => c.User)
.HasForeignKey(c => c.UserId)
.WillCascadeOnDelete(false);

base.OnModelCreating(modelBuilder);
}
}

可以有其他实体和关系,可以导致您的模型中的问题,但评论从您的示例看起来显而易见。


I'm new to EF code first principal and currently with no clue what to do.. I have 2 POCO classes..

public class Problem
{
    public int ProblemID { get; set; }
    public int UserID { get; set; }
    public int CategoryID { get; set; }
    public int RatingID { get; set; }

    public string Title { get; set; }
    public string Description { get; set; }        
    public double Latitude { get; set; }
    public double Longitude { get; set; }
    public int State { get; set; }
    public DateTime CreatedOn { get; set; }

    public virtual Rating Rating { get; set; }
    public virtual Category Category { get; set; }
    public virtual User User { get; set; }

    public virtual ICollection<Picture> Pictures { get; set; }
    public virtual ICollection<Comment> Comments { get; set; }
}

and

public class User
{
    public int UserID { get; set; }
    public int RoleID { get; set; }

    public string Name { get; set; }
    public string Surname { get; set; }
    public string Email { get; set; }
    public string Password { get; set; }
    public string SocialHandle { get; set; }       
    public DateTime RegisteredOn { get; set; }

    public virtual Role Role { get; set; }

    public virtual ICollection<Point> Points { get; set; } 
    public virtual ICollection<Problem> Problems { get; set; }
    public virtual ICollection<Comment> Comments { get; set; }               
}

My database creation is ok, but when I try to init some data in it using custom initializer, I'm getting following error :

Introducing FOREIGN KEY constraint 'Problem_User' on table 'Problems' may cause cycles or multiple cascade paths. Specify ON DELETE NO ACTION or ON UPDATE NO ACTION, or modify other FOREIGN KEY constraints.
Could not create constraint. See previous errors.

This is my initializer :

protected override void Seed(CleanStreets context)
    {
        var adminRole = new Role { Name = "Administrator", RoleID = 0 };            
        var moderatorRole = new Role { Name = "Moderator", RoleID = 1 };
        var userRole = new Role { Name = "User", RoleID = 2 };

        context.Roles.Add(adminRole);
        context.Roles.Add(userRole);
        context.Roles.Add(moderatorRole);

        var admin = new User { Name = "admin", Surname = "admin", Role = adminRole, Email = "fake@fake.com", Password = "", RegisteredOn = DateTime.Now, SocialHandle = null };
        var user = new User { Name = "user", Surname = "user", Role = userRole, Email = "fake@fake2.com", Password = "", RegisteredOn = DateTime.Now, SocialHandle = null };

        context.Users.Add(admin);
        context.Users.Add(user);

        var categoryOne = new Category { Title = "Komunalni problemi", CategoryID = 0 };
        var categoryTwo = new Category { Title = "Ostali problemi", CategoryID = 1 };

        context.Categories.Add(categoryOne);
        context.Categories.Add(categoryTwo);

        var problem = new Problem { Category = categoryOne, Title = "Prvi testni problem", Description = "Ovo je testni opis", Latitude = 45.5, Longitude = 15.5, State = 0, CreatedOn = DateTime.Now, User = user };

        context.Problems.Add(problem);

        base.Seed(context);
    }

What I'm doing wrong? Thank you in advance!

解决方案

That will be because of Comments. EF by default uses cascade deletes on references. In your case the cascade delete will be created from User -> Problem, User -> Comment but also from Problem -> Comment. If you deleted User cascading to the same comment record can come from both Problem and User. That is not allowed in SQL Server. Each record can be accessible by only single cascade delete path.

To avoid this you must use fluent mapping to turn of cascade delete on one relation (you must make choice which one). The example for User -> Comment

public class Context : DbContext
{
    public DbSet<User> Users { get; set; }
    public DbSet<Comment> Comments { get; set; }
    public DbSet<Problem> Problems { get; set; }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Entity<User>()
                    .HasMany(u => u.Comments)
                    .HasRequired(c => c.User)
                    .HasForeignKey(c => c.UserId)
                    .WillCascadeOnDelete(false);

        base.OnModelCreating(modelBuilder);
    }
} 

There can be other entities and relations which can cause this problem in your model but Comment looks obvious from your example.

这篇关于实体框架代码第一 - FOREIGN KEY约束问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆