Reputation: 9288
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);
}
Upvotes: 2
Views: 97
Reputation: 1064044
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 Hall
instances, it is inserting them.
There are 2 ways to address this:
Halls
from your non-L2S model to the L2S model, you could ask the data-context for the matching instance, i.e. in a loop, use ctx.Halls.FirstOrDefault(...)
to get the equivalent Hall
from the data-context, and add that instead of the originalAttach
method (i.e. ctx.Halls.Attach(...)
) to make L2S aware of the hall instances before you startUpvotes: 3