如何为LINQ to SQL编写Upsert?

JC *_*bbs 18 linq linq-to-sql

所以我想为LINQ to SQL编写一个通用的Upsert函数,我在构思它的过程中遇到了一些麻烦.我希望它能像这样工作:

var db = new DataContext();
db.Customers.UpsertOnSubmit(customer);
Run Code Online (Sandbox Code Playgroud)

所以它必须在某种程度上是通用的,我猜和表上的扩展方法.在确定基础表的主键时,我已经能够做到这一点:

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

我假设有必要让这个来组成一个查询来判断该项是否已经在数据库中,但我现在还不知道如何处理它.

eri*_*cvg 8

我做了类似的事情,但采用了不同的方法.每个实体都实现IEntity.IEntity如果对象是新对象或现有对象,则属性之一是状态.然后,我为每个实体实现,例如:

public EntityState EntityState
{
    get
    {
        if (_Id > 0)
            return EntityState.Exisiting;
        else
            return EntityState.New;
    }
}
Run Code Online (Sandbox Code Playgroud)

然后,泛型Upsert可以(在通用存储库类型类上):

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>();
}
Run Code Online (Sandbox Code Playgroud)

如果从另一个datacontext附加,还要确保在对象上有时间戳.

  • 嗯...一个upsert的重点是你不知道它是否存在,你只是想让数据库拥有新的内容; upsert会为您节省"额外往返"以确定.你的解决方案没有回答这个问题 我们需要的是一个sql`MERGE`,如下所述:http://stackoverflow.com/questions/2479488/syntax-for-single-row-merge-upsert-in-sql-server. (2认同)