1

I'm going to create a new cascade [node] --1:many-- [currency] --1:many-- [unit] defined using EF 6.x Code First:

public class CashFlowSpendableMinimumNode {
  ...
  [ForeignKey("CashFlowSpendableMinimumNodeId")]
  public ICollection<CashFlowSpendableMinimumCurrency> CashFlowSpendableMinimumCurrencies { get; private set; }
  ...
}
public class CashFlowSpendableMinimumCurrency {
  ...
  public int CashFlowSpendableMinimumNodeId { get; set; }
  [ForeignKey("CashFlowSpendableMinimumNodeId")]
  public CashFlowSpendableMinimumNode CashFlowSpendableMinimumNode { get; set; 
  ...
  [ForeignKey("CashFlowSpendableMinimumCurrencyId")]
  public ICollection<CashFlowSpendableMinimumUnit> CashFlowSpendableMinimumUnits { get; set; }
  ...
}

public class CashFlowSpendableMinimumUnit {
  ...
  public int CashFlowSpendableMinimumCurrencyId { get; set; }
  [ForeignKey("CashFlowSpendableMinimumCurrencyId")]
  public CashFlowSpendableMinimumCurrency CashFlowSpendableMinimumCurrency { get; set; }
  ...
}

The first part i.e. relation between node--currency work as expected: I create a new currency instance and add it to DbSet<CashFlowSpendableMinimumCurrency> -> it appears in the navigation property (collection) nodeMinimum.CashFlowSpendableMinimumCurrencies and its Id is resolved properly when relation is saved to DB.

The second relation currency--unit does not work even if I tried to define it the same way as the first relation between node--currency: when I create a new unit instance and add it to DbSet<CashFlowSpendableMinimumUnit> it does not appear in the navigation property currMinimum.CashFlowSpendableMinimumUnits and if I continue execution, an attempt to make cascade persistent by calling SaveChanges() later results in the error in the %subject%.

UPDATE 1

I omit exact wording of error message, here it is:

Unable to determine the principal end of the 'xxx.yyy.Database.CashFlowSpendableMinimumNode_CashFlowSpendableMinimumCurrencies' relationship. Multiple added entities may have the same primary key.

UPDATE 2

The only solution to make it running I've discovered is to flush the change tracker prematurely:

foreach (var node in nodes)
{
   nodeMinimum = new ...
   DbSet<CashFlowSpendableMinimumNode>.Add(nodeMinimum);
   foreach (var curr in currencies)
   {
      currMinimum = new ...
      DbSet<CashFlowSpendableMinimumCurrency>.Add(currMinimum);

      DbContext.SaveChanges();  //The premature flush to fix a problem

      foreach (var unit in units)
      {
         unitMinimum = new ...
         DbSet<CashFlowSpendableMinimumUnit>.Add(unitMinimum);
      }
   }
}
DbContext.SaveChanges();
...

UPDATE 3

Concerning discused constructors and instance creation:

public CashFlowSpendableMinimumCurrency()
{
  CashFlowSpendableMinimumUnits = new List<CashFlowSpendableMinimumUnit>();
}

[...]
CashFlowSpendableMinimumCurrency result = new CashFlowSpendableMinimumCurrency()
{
  CurrencyCode = ACurrencyCode,  // the attached entity
  Curr = ACurrencyCode.Curr,     // string
  Minimum = minimum,  //decimal
  Median = median,  //decimal
  CashFlowSpendableMinimumNode = ANodeMinimum,  // parent in 1:n relation, EntityState.Added
  ExchangeRate = 1, //decimal
  DeclaredExchangeRate = false,
  BanknotesContribution = 0, //double
  BanknotesSpendableMinimum = 0, //decimal
  CoinsContribution = 0, //double
  CoinsSpendableMinimum = 0, //decimal
};
ADbContext.CashFlowSpendableMinimumCurrencies.Add(result);

Please, does anybody see, what is wrong?

Thanks, pf

pf1957
  • 997
  • 1
  • 5
  • 20
  • 1
    The definition `[ForeignKey("CashFlowSpendableMinimumCurrencyId")]` in `CashFlowSpendableMinimumCurrency` looks to be the problem. You're defining a collection of objects as a foreign key? Remove this and that should resolve the problem. – Barry O'Kane Jun 08 '16 at 13:04
  • No, I'm telling collection where to get items... If I tried to remove it, EF has dropped existing FK _CashFlowSpendableMinimumCurrencyId_ in the DB, but introduced a new int field _CashFlowSpendableMinimumCurrency_Id_ and declared it as FK. From refererence integrity point of view it is the same. But EF works. Why this happens? – pf1957 Jun 08 '16 at 13:21
  • And why the analogical FK definition in the _CashFlowSpendableMinimumNode_ does not bother? – pf1957 Jun 08 '16 at 13:23
  • And what is the worst I've the similiar cascade node-currency-unit _CashFlowOptimizedXXX_ with the FK declared the same way and it works as expected over one year ... – pf1957 Jun 08 '16 at 13:35
  • @BarryO'Kane, I've looked closer what happens if I removed FK definition as you suggested and it does not works: EF removes FK constraint from _CashFlowSpendableMinimuCurrencyId_, creates a new _int_ field _CashFlowSpendableMinimuCurrency_Id_ and add FK constraint to it. The error disappears, but: EF resolves FK values in original field _CashFlowSpendableMinimuCurrencyId_ (withouth FK) and new field _CashFlowSpendableMinimuCurrencyId_ left **null**, hence cascaded operations does not work, new item is not added into navigation property etc... – pf1957 Jun 08 '16 at 14:42
  • It really would help to see running code in stead of some fragments. I don't know where `nodes` or `currencies` come from. Do they contains attached entities? Also, what happens in the entities' constructors (if anything)? – Gert Arnold Jun 09 '16 at 06:52
  • @GertArnold I understand, but actually it is rather huge code to be published here. _nodes_ and _currencies_ are arrays/lists gotten via LINQ - it should contains attached entities (EF complains on currency-unit relation, not to PK collision of another unattached entities) In the constructors, relations via object reference are established, and the most of properties is initialized. If your objection would be true, IMHO the premature SaveChanges would not solve the problem. – pf1957 Jun 09 '16 at 08:03
  • OK, I understand. Just make sure you [don't initialize references navigation properties in constructors.](http://stackoverflow.com/a/20773057/861716). – Gert Arnold Jun 09 '16 at 08:26
  • @GertArnold I ammended question text by code fragment concerning instance constructions. – pf1957 Jun 09 '16 at 09:30

0 Answers0