2016-11-20 6 views
0

Je veux avoir deux lignes pour chaque transfert qui sont poi je:Entity Framework circulaire de référence dans la même table avec les deux requis

public class Transfer : DependentRestrictedEntity 
{ 
    public virtual Account Acount { set; get; } 
    public DateTime Time { set; get; } 
    public Transfer PairedTransfer { set; get; } 
    [NotMapped] 
    public override RestrictedEntity DependentOn => Acount; 
    //other code. 
} 

public class Account : RestrictedEntity 
{   
    public string Name { get; set; } 
    //other code. 
} 

public class RestrictedEntity : Entity 
{ 
    public Filter Filter { get; set; } 
    //other code. 
} 

public abstract class DependentRestrictedEntity : RestrictedEntity 
{ 
    [NotMapped] 
    public abstract RestrictedEntity DependentOn { get; } 
    //other code. 
} 

public class Entity 
{ 
    [Key, JsonProperty, DatabaseGenerated(DatabaseGeneratedOption.Identity)] 
    public Guid ID { set; get; } 
    //other code. 
} 

public class MyMoneyContext : UserDbContext 
{ 
    public DbSet<Account> Accounts { get; set; } 
    public DbSet<Transfer> Transfers { get; set; } 

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


     _modelBuilder.Entity<Transfer>() 
      .HasRequired(_t => _t.PairedTransfer) 
      .WithRequiredDependent(); 
    } 
    //other code 
} 

D'une certaine façon j'ai besoin paire 2 Transferts. L'un d'eux devrait appartenir au 1er compte, et le second devrait appartenir au 2e compte. Les utilisateurs qui ont des autorisations pour le premier compte mais qui n'ont pas l'autorisation de second compte ne devraient pas pouvoir voir ces deux entrées.

Problème ici est que je ne sais pas comment ajouter une nouvelle entrée. J'ai essayé:

var accounts = Database.Accounts.ToList(); 
Transfer pair, pair2; 
Database.Transfers.Add(
    pair = new Transfer() 
    { 
     ID = Guid.NewGuid(), 
     Ammount = 100, 
     Filter = accounts[0].Filter, 
     Acount = accounts[0], 
    } 
); 

Database.Transfers.Add 
(
    pair2 = new Transfer() 
    { 
     ID = Guid.NewGuid(), 
     Ammount = -100, 
     Filter = accounts[1].Filter, 
     Acount = accounts[1], 
    } 
); 
pair.PairedTransfer = pair2; 
pair2.PairedTransfer = pair; 

Database.SaveChanges(); 

Mais je reçois un problème de référence circulaire.

Répondre

0

Le problème est que EF ne sait pas quel transfert ajouter à la base de données d'abord, parce que 1. ont référence à 2. et 2. se référer à 1. (donc il ne peut pas affecter les clés étrangères)

I recommande d'insérer le premier transfert avec PairedTransfer nul, puis insérer le second avec assigné d'abord PairedTransfer, puis finalement assigner au second transfert au PairedTransfer d'abord :)

+0

Je comprends quel est le problème, je ne sais pas comment le résoudre. Mais les deux sont requis (pas nul), donc je ne sais pas comment ajouter une ligne avec null? – Vasoli

+0

Oh, maintenant je vois que vous utilisez l'API fluide pour indiquer que PairedTransfer est requis ... alors dans ce cas, vous pouvez utiliser un transfert "fictif" qui aura le rôle d'un null (juste à cet effet). Ou si vous le pouvez, ne le déclarez pas comme requis. – MacakM

+0

Et comment créer un 1er objet factice. Peut-être que cet objet peut se référencer? Puis-je en quelque sorte dire que tout cela est en 1 transaction? Je ne veux pas laisser DB inconsistant. – Vasoli