使用LINQ to SQL批量插入和复制记录

时间:2010-08-26 03:24:04

标签: c# linq-to-sql bulkinsert

是否存在处理批量插入的“最佳实践”方法(通过LINQ)但丢弃可能已存在于表中的记录?或者我将不得不在导入表中批量插入然后删除重复项,或者一次插入一条记录?


08/26/2010 - 编辑#1:
我现在正在研究Intersect和Except方法。我正在收集来自不同来源的数据,转换成List,想要“比较”到目标数据库,然后只插入新记录。

List<DTO.GatherACH> allACHes = new List<DTO.GatherACH>();
State.IState myState = null;
State.Factory factory = State.Factory.Instance;
foreach (DTO.Rule rule in Helpers.Config.Rules)
{
    myState = factory.CreateState(rule.StateName);
    List<DTO.GatherACH> stateACHes = myState.GatherACH();
    allACHes.AddRange(stateACHes);
}

List<Model.ACH> newRecords = new List<Model.ACH>();  // Create a disconnected "record set"...
foreach (DTO.GatherACH record in allACHes)
{
        var storeInfo = dbZach.StoreInfoes.Where(a => a.StoreCode == record.StoreCode && (a.TypeID == 2 || a.TypeID == 4)).FirstOrDefault();

        Model.ACH insertACH = new Model.ACH
        {
            StoreInfoID = storeInfo.ID,
            SourceDatabaseID = (byte)sourceDB.ID,
            LoanID = (long)record.LoanID,
            PaymentID = (long)record.PaymentID,
            LastName = record.LastName,
            FirstName = record.FirstName,
            MICR = record.MICR,
            Amount = (decimal)record.Amount,
            CheckDate = record.CheckDate
        };
        newRecords.Add(insertACH);
}

上面的代码构建了newRecords列表。现在,我试图通过比较3字段唯一索引来获取此列表中不在数据库中的记录:

AchExceptComparer myComparer = new AchExceptComparer();
var validRecords = dbZach.ACHes.Intersect(newRecords, myComparer).ToList();

比较器看起来像:

class AchExceptComparer : IEqualityComparer<Model.ACH>
{
    public bool Equals(Model.ACH x, Model.ACH y)
    {
        return (x.LoanID == y.LoanID && x.PaymentID == y.PaymentID && x.SourceDatabaseID == y.SourceDatabaseID);
    }

    public int GetHashCode(Model.ACH obj)
    {
        return base.GetHashCode();
    }
}

但是,我收到此错误:

  
    

LINQ to Entities无法识别方法'System.Linq.IQueryable 1[MisterMoney.LARS.ZACH.Model.ACH] Intersect[ACH](System.Linq.IQueryable 1 [MisterMoney.LARS.ZACH.Model.ACH],System.Collections.Generic.IEnumerable 1[MisterMoney.LARS.ZACH.Model.ACH], System.Collections.Generic.IEqualityComparer 1 [MisterMoney .LARS.ZACH.Model.ACH])'方法,并且此方法无法转换为商店表达式。

  

有什么想法吗?是的,这与原始问题完全一致。 :)

3 个答案:

答案 0 :(得分:1)

你不能使用LINQ to SQL进行批量插入(当你说“LINQ”时,我假设你指的是LINQ to SQL)。但是,根据您的描述,我建议您查看SQL Server 2008的新MERGE运算符。 Inserting, Updating, and Deleting Data by Using MERGE

Another example here.

答案 1 :(得分:0)

要注意的一件事是,如果排队超过2000条记录而不调用SubmitChanges() - TSQL对每次执行的语句数量有限制,因此您不能简单地排队每条记录然后调用SubmitChanges( )因为这将抛出SqlException,您需要定期清除队列以避免这种情况。

答案 2 :(得分:0)

我建议你自己编写SQL来进行插入,我发现它要快得多,你可以让它按照你想要的方式工作。当我做了类似的事情(只是一个一次性的程序)时,我只是用一个字典来保存我已插入的ID,以避免重复。

我发现LINQ to SQL适用于在LINQ to SQL中完成整个生命周期的一条记录或一小组。

或者您可以尝试使用SQL Server 2008's Bulk Insert