I have 3 classes:
BasePlace, Hall, HallPlan.
Relations:
BasePlace - Hall: one-to-many.
Hall – HallPlan: one-to-many.
I get places(venues) from remote program. I have the following method to add(or update) object:
public void AddPremieraPlace(IEnumerable<BasePlace> places)
{
if(places != null)
{
foreach (var place in places)
{
//is exist in db
var dbPlace = Database.BasePlaces.FirstOrDefault(p => p.OIDPremiera == place.OIDPremiera);
// if exist update properties and collections
if (dbPlace != null)
{
dbPlace.Name = place.Name
dbPlace.Halls = place.Halls;
}
else
Add(place); // just add new place
Database.SubmitChanges();
}
}
}
When place is exist in the DB then updates works not properly. In the Hall and HallPlan creates duplicate:
Hall table, for example:
OID Name PlaceId OIDPremiera
19 Redisson NULL 1
20 Test 2 NULL 3
21 Test 3 NULL 2
22 Redisson 5 1
23 Test 2 5 3
24 Test 3 5 2
How to update correctly?
Thanks.
Add():
public virtual void Add(TClass entity)
{
Check.Argument.IsNotNull(entity, "entity");
Database.GetTable<TClass>().InsertOnSubmit(entity);
}
LINQ-to-SQL has an identity manager; if it finds something in the tree that it doesn’t recognise (i.e. isn’t in the identity manager), then it assumes it is to be treated as an insert for that item. So because it doesn’t recognise your
Hallinstances, it is inserting them.There are 2 ways to address this:
Hallsfrom your non-L2S model to the L2S model, you could ask the data-context for the matching instance, i.e. in a loop, usectx.Halls.FirstOrDefault(...)to get the equivalentHallfrom the data-context, and add that instead of the originalAttachmethod (i.e.ctx.Halls.Attach(...)) to make L2S aware of the hall instances before you start