4

I have 3 classes, related to 3 database tables:

public class Stat
{
    public int Id { get; set; }
    public string Name { get; set; }
    public List<Quantity> Quantities { get; set; }
}
public class Quantity
{
    public int Id { get; set; }
    public string Name { get; set; }
    public virtual Stat Stat { get; set; }
    public virtual Unit Unit { get; set; }
}
public class Unit
{
    public int Id { get; set; }
    public string Name { get; set; }
    public string Abbreviation { get; set; }
    public List<Quantity> Quantities { get; set; }
}

A Stat can have a list of Quantities, and a Quantity have one Unit. If I want to save a Stat with Entity Framework, I have to iterate through its list of Quantities, and check if the Quantity already exists, or newly created (the data comes from an HTML Form).

public void UpdateStat(Stat stat)
{
    foreach (Quantity q in stat.Quantities)
    {
        if (q.Id == 0)
        {
            db.Quantities.Add(q);
        }
        else
        {
            db.Entry(q).State = EntityState.Modified;
        }
    }
    db.Entry(stat).State = EntityState.Modified;
    db.SaveChanges();
}

The problem is, when more Quantities have the same Unit, an error occurs: "An object with the same key already exists in the ObjectStateManager. The ObjectStateManager cannot track multiple objects with the same key."

I have no idea, how a Stat can be updated with the list of its Quantities and Units together.

4
  • Are you using code first? Does the DB have increment set on your Id columns? Commented Aug 3, 2013 at 20:03
  • Yes, I use code first, and the DB auto increments the IDs, but I didn't set anything... Commented Aug 3, 2013 at 20:12
  • Is stat attached to the context? If so you do not need to add the entities individually, simply having them in the Quantities collection of stat will apply the appropriate operation. Commented Aug 3, 2013 at 22:34
  • I use guids for my Id's so I don't use auto-inc too much, but what happens if you don't ever set the Id's on your model? His are all 0 if added, is EF smart enough to know that it's okay with auto-inc? Commented Aug 4, 2013 at 7:48

1 Answer 1

1

As you mentioned, the problem occurs when more than one quantity has same Unit. To avoid adding same unit multiple time you can check if a unit is already in the db. If it exists then reuse the existing unit.

if (q.Id == 0)
{
   var unit=db.Units.FirstOrDefault(u=>u.Id==q.Unit.Id);
   if(unit!=null)
      q.Unit=unit;
   db.Quantities.Add(q);
}
Sign up to request clarification or add additional context in comments.

1 Comment

using SingleOrDefault(u=>u.Id==q.Unit.Id) would be more appropriate,if there are two records with same id the FirstOrDefault would fetch those records and would give you the first item whereas singleOrDefault would only give you a single item and return null if there are no records.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.