Сначала Entity Framework Code - проблема ограничения FOREIGN KEY - PullRequest
8 голосов
/ 09 сентября 2011

Я новичок в коде EF, первый принципал, и в настоящее время не знаю, что делать .. У меня есть 2 класса POCO ..

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; }
}

и

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; }               
}

Моя база данныхсоздание в порядке, но когда я пытаюсь инициировать некоторые данные в нем с помощью пользовательского инициализатора, я получаю следующую ошибку:

Введение ограничения FOREIGN KEY 'Problem_User' в таблицу 'Проблемы' может вызвать циклы илинесколько каскадных путей.Укажите ON DELETE NO ACTION или ON UPDATE NO ACTION или измените другие ограничения FOREIGN KEY.
Не удалось создать ограничение.См. Предыдущие ошибки.

Это мой инициализатор:

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);
    }

Что я делаю не так?Заранее спасибо!

1 Ответ

15 голосов
/ 09 сентября 2011

Это будет из-за Comments. EF по умолчанию использует каскадные удаления по ссылкам. В вашем случае каскадное удаление будет создано из Пользователь -> Проблема, Пользователь -> Комментарий, но также из Проблемы -> Комментарий. Если вы удалили каскадирование пользователя к одной и той же записи комментария, это может быть как Problem, так и User. Это не разрешено в SQL Server. Каждая запись может быть доступна только по одному пути каскадного удаления.

Чтобы избежать этого, вы должны использовать плавное отображение для поворота каскадного удаления по одному отношению (вы должны выбрать, какое из них). Пример для пользователя -> Комментарий

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);
    }
} 

Могут быть другие сущности и отношения, которые могут вызвать эту проблему в вашей модели, но Comment выглядит очевидным из вашего примера.

...