I have two entities Employee
and Asset
. They are defined as:
public class Employee
{
public Employee()
{
this.Assets = new List<Asset>();
}
public int EmployeeID { get; set; }
public string Name { get; set; }
public virtual List<Asset> Assets { get; set; }
}
public class Asset
{
public string FacilityAssetID { get; set; }
public string Name { get; set; }
public string Description { get; set; }
}
Fluent defines the schema as:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Employee>().ToTable("Employees");
modelBuilder.Entity<Employee>().HasKey(e => e.EmployeeID);
modelBuilder.Entity<Employee>().Property(e => e.Name).HasMaxLength(50).IsRequired();
modelBuilder.Entity<Employee>().HasMany(e => e.Assets).WithMany().Map(m => m.MapLeftKey("EmployeeID").MapRightKey("FacilityAssetID").ToTable("EmployeeToAsset"));
modelBuilder.Entity<Asset>().ToTable("Assets");
modelBuilder.Entity<Asset>().HasKey(a => a.FacilityAssetID);
modelBuilder.Entity<Asset>().Property(a => a.Name).HasMaxLength(50).IsRequired();
modelBuilder.Entity<Asset>().Property(a => a.Description).HasMaxLength(200).IsRequired();
base.OnModelCreating(modelBuilder);
}
Now, I have some employees in the tables as well as some assets. The assets are populated using a web service. Suppose I have the following assets:
- {FacilityAssetID}, {Name}, {Description}
- Asset1F32, Spindle Head, SomeDesc
- Asset1C53, Milling Block, SomeDesc
There are two assets with IDs: Asset1F32 and Asset1C53. If I try to add an asset to an employee using the following code, I can successfully add an asset:
using (VCContext context = new VCContext())
{
Employee emp = context.Employees.First();
Asset assetDetached = new Asset() { FacilityAssetID = "Asset1F32" };
context.Assets.Attach(assetDetached);
emp.Assets.Add(assetDetached);
context.SaveChanges();
}
If I loop through some of the assets beforehand and try to add an asset, it will throw an exception. Here's that code:
using (VCContext context = new VCContext())
{
foreach (Employee employee in context.Employees)
{
Console.WriteLine(employee.Name);
foreach (Asset asset in employee.Assets)
{
Console.WriteLine(string.Format(" - {0}", asset.FacilityAssetID));
}
}
Employee emp = context.Employees.First();
Asset assetDetached = new Asset() { FacilityAssetID = "Asset1F32" };
context.Assets.Attach(assetDetached); // EXCEPTION HERE!!!
emp.Assets.Add(assetDetached);
context.SaveChanges();
}
The exception thrown is:
Attaching an entity of type 'ASTC.Asset' failed because another entity of the same type already has the same primary key value. This can happen when using the 'Attach' method or setting the state of an entity to 'Unchanged' or 'Modified' if any entities in the graph have conflicting key values. This may be because some entities are new and have not yet received database-generated key values. In this case use the 'Add' method or the 'Added' entity state to track the graph and then set the state of non-new entities to 'Unchanged' or 'Modified' as appropriate.
Why would it throw an exception in the second case but not the first case? Additionally, how can I add the detached asset in the second scenario?