user348173
user348173

Reputation: 9288

Update objects LinqToSql

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

Answers (1)

Marc Gravell
Marc Gravell

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:

  • rather than directly assigning the 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 original
  • use the Attach method (i.e. ctx.Halls.Attach(...)) to make L2S aware of the hall instances before you start

Upvotes: 3

Related Questions