Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How would you write an Upsert for LINQ to SQL?

So I'd like to write a generic Upsert function for LINQ to SQL and I'm having some trouble conceptualizing how to do it. I'd like it to work something like this:

var db = new DataContext();
db.Customers.UpsertOnSubmit(customer);

So it would have to be generic in some way and I guess and extension method on Table. I've been able to get this far in determining the primary key of the underlying table:

var context = source.Context;
var table = context.Mapping.GetTable(source.GetType());
var primaryMember = table.RowType.DataMembers.SingleOrDefault(m => m.IsPrimaryKey);

I'm assuming it will be necessary to have this to compose a query to tell if the item is in the DB already or not but I don't really know what to do with it at this point.

like image 446
JC Grubbs Avatar asked Mar 12 '09 02:03

JC Grubbs


People also ask

What is Upsert command in SQL?

SQL Beginner's Guide The word UPSERT combines UPDATE and INSERT , describing it statement's function. Use an UPSERT statement to insert a row where it does not exist, or to update the row with new values when it does.

What you can do with LINQ to SQL?

When the application runs, LINQ to SQL translates into SQL the language-integrated queries in the object model and sends them to the database for execution. When the database returns the results, LINQ to SQL translates them back to objects that you can work with in your own programming language.

Is LINQ converted to SQL?

LINQ to SQL offers an infrastructure (run-time) for the management of relational data as objects. It is a component of version 3.5 of the . NET Framework and ably does the translation of language-integrated queries of the object model into SQL. These queries are then sent to the database for the purpose of execution.

How do you update a record in LINQ?

You can update rows in a database by modifying member values of the objects associated with the LINQ to SQL Table<TEntity> collection and then submitting the changes to the database. LINQ to SQL translates your changes into the appropriate SQL UPDATE commands.


Video Answer


1 Answers

I do something similar, but with a different approach. Every entity implements IEntity. One of the properties of IEntity is a state if the object is new or existing. I then implement that for each entity, like:

public EntityState EntityState
{
    get
    {
        if (_Id > 0)
            return EntityState.Exisiting;
        else
            return EntityState.New;
    }
}

Then, a generic Upsert could be (on a generic repository type class):

public virtual void Upsert<Ta>(Ta entity)
    where Ta: class
{
    if (!(entity is IEntity))
        throw new Exception("T must be of type IEntity");

    if (((IEntity)entity).EntityState == EntityState.Exisiting)
        GetTable<Ta>().Attach(entity, true);
    else
        GetTable<Ta>().InsertOnSubmit(entity);
}

private System.Data.Linq.Table<Ta> GetTable<Ta>()
    where Ta: class
{
    return _dataContext.Context.GetTable<Ta>();
}

If your attaching from another datacontext, also make sure you have a timestamp on your objects.

like image 123
ericvg Avatar answered Nov 11 '22 21:11

ericvg