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.
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.
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.
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.
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.
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.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With