2016-08-16 2 views
0

Я прочитал много тем о картировании User и Friends, но я не смог найти хороший ответ. Я хочу, чтобы ApplicationUser имел возможность иметь ноль для многих запросов для друзей, а затем - для многих друзей.Пользователь модели -> FriendRequests с Entity Framework code first

Как вы можете видеть в модели FriendRequest имеет два ApplicationUsers, как User и FutureFriend, и это то, что вызывает проблемы.

public class ApplicationUser : IdentityUser<int, CustomUserLogin, CustomUserRole,CustomUserClaim> 
{ 
    public async Task<ClaimsIdentity> GenerateUserIdentityAsync(UserManager<ApplicationUser, int> manager, string authenticationType) 
    { 
CookieAuthenticationOptions.AuthenticationType 
     var userIdentity = await manager.CreateIdentityAsync(this, authenticationType); 
     // Add custom user claims here 
     return userIdentity; 
    } 

    public ApplicationUser() 
    { 
    } 

    [Required] 
    public string Alias { get; set; } 

    public virtual ICollection<FriendRequest> FriendRequests { get; set; } 
} 

public class FriendRequest 
{ 
    public int UserId { get; set; } 
    public int FutureFriendId { get; set; } 
    public virtual ApplicationUser User { get; set; } 
    public virtual ApplicationUser FutureFriend { get; set; } 
    public DateTime? RequestTime { get; set; } 
} 

protected override void OnModelCreating(DbModelBuilder modelBuilder) 
{ 
    base.OnModelCreating(modelBuilder); 

    modelBuilder.Entity<ApplicationUser>() 
    .HasMany(u => u.FriendRequests) 
    .WithRequired(f => f.User) 
    .HasForeignKey(f => f.UserId); 

    modelBuilder.Entity<FriendRequest>() 
    .HasKey(f => new { f.UserId, f.FutureFriendId }); 

    modelBuilder.Entity<FriendRequest>() 
    .HasRequired(f => f.FutureFriend) 
    .WithMany() 
    .HasForeignKey(f => f.FutureFriendId); 

    //Did not work either 
    //modelBuilder.Entity<FriendRequest>().HasKey(f => new { UserId = f.UserId, FutureFriendId = f.FutureFriendId }); 
    //modelBuilder.Entity<FriendRequest>() 
    // .HasRequired(f => f.User) 
    // .WithMany() 
    // .HasForeignKey(f => f.UserId); 
    //modelBuilder.Entity<FriendRequest>() 
    // .HasRequired(f => f.FutureFriend) 
    // .WithMany() 
    // .HasForeignKey(f => f.FutureFriendId) 
    // .WillCascadeOnDelete(false); 
} 

Ошибка при попытке создать базу данных:

Вводя ограничение внешнего ключа «FK_dbo.FriendRequests_dbo.AspNetUsers_UserId» на стол «FriendRequests» может вызвать циклы или несколько путей порогов. Укажите ВКЛ. УДАЛИТЬ НЕТ ДЕЙСТВИЙ или НЕ ОБНОВИТЬ НЕТ ДЕЙСТВИЙ, или изменить другие ограничения FOREIGN KEY. Не удалось создать ограничение или индекс. См. Предыдущие ошибок.

Update:

Решил переделать класс, окончательное решение может быть найдено здесь: SO

+1

Добавить '.WillCascadeOnDelete (ложь)' после того, как один из '.HasForeignKey (..)' вызовов. –

+1

@ ИванСтоев Спасибо! Это сработало, добавлено '.WillCascadeOnDelet e (false)' на обоих. .HasForeignKey (..) ' – Ogglas

ответ

1

Спасибо @IvanStoev!

Одно из решений моей модели - отключить .WillCascadeOnDelet‌​e(false) на одном или обоих из .HasForeignKey(..). Поскольку CASCADE вызывает удаление соответствующих строк из таблицы ссылок, если эта строка удалена из родительской таблицы ... и я немного параноидальный.

Я решил отключить CascadeDeleteConvention как от одного до многих отношений, так и от многих до многих релизов.

Мое решение:

modelBuilder.Conventions.Remove<OneToManyCascadeDeleteConvention>(); 
modelBuilder.Conventions.Remove<ManyToManyCascadeDeleteConvention>(); 

Возможное решение:

modelBuilder.Entity<ApplicationUser>() 
    .HasMany(u => u.FriendRequests) 
    .WithRequired(f => f.User) 
    .HasForeignKey(f => f.UserId) 
    .WillCascadeOnDelete(false); 

modelBuilder.Entity<FriendRequest>() 
    .HasKey(f => new { f.UserId, f.FutureFriendId }); 

modelBuilder.Entity<FriendRequest>() 
    .HasRequired(f => f.FutureFriend) 
    .WithMany() 
    .HasForeignKey(f => f.FutureFriendId) 
    .WillCascadeOnDelete(false); 
Смежные вопросы