2016-08-16 2 views
0

Ich habe viele Threads über das Mapping User und Friends gelesen, aber ich konnte keine gute Antwort finden. Was ich will ist, dass ein ApplicationUser in der Lage sein sollte, null zu viele Freundschaftsanfragen und später Null zu vielen Freunden zu haben.Modell Benutzer -> FriendRequests mit Entity Framework Code zuerst

Wie Sie im Modell sehen FriendRequest zwei ApplicationUsers hat, sowohl User und FutureFriend und das ist, was Probleme verursacht.

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

Fehler bei dem Versuch, die Datenbank zu erstellen:

FOREIGN KEY Constraint 'FK_dbo.FriendRequests_dbo.AspNetUsers_UserId' Einführung auf Tabelle 'FriendRequests' können Zyklen oder mehrere kaskadenWege verursachen. Geben Sie ON DELETE NO ACTION oder ON UPDATE NO ACTION an, oder ändern Sie andere FOREIGN KEY-Einschränkungen. Constraint oder Index konnte nicht erstellt werden. Siehe vorherige Fehler.

Update:

Beschlossen, die Klasse neu zu gestalten, kann Endlösung hier: SO

+1

Add '.WillCascadeOnDelete (false)' nach einem der '.HasForeignKey (..)' Anrufe. –

+1

@IvanStoev Danke! Dies funktionierte, fügte '.WillCascadeOnDelet e (false)' auf beiden '.HasForeignKey (..)' hinzu – Ogglas

Antwort

1

Danke @IvanStoev!

Eine Lösung in meinem Modell ist die Deaktivierung .WillCascadeOnDelet‌​e(false) auf einer oder beiden der .HasForeignKey(..). Da CASCADE bewirkt, dass entsprechende Zeilen aus der referenzierenden Tabelle gelöscht werden, wenn diese Zeile aus der übergeordneten Tabelle gelöscht wird ... und ich bin ein wenig paranoid.

Ich entschied mich, die CascadeDeleteConvention sowohl für ein-zu-viele-Beziehungen als auch für viele bis viele Verknüpfungen zu deaktivieren.

Meine Lösung:

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

Mögliche Lösung:

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); 
Verwandte Themen