Linq InsertAllOnSubmit,如果不存在

本文关键字:如果不 不存在 如果 InsertAllOnSubmit Linq | 更新日期: 2023-09-27 18:05:44

插入不存在的记录:

using(MyDataContext db = new MyDataContext())
{
    for(int i=0 i<Items.Length;i++)
    {
        if(!db.Items.Any(item=> item.name == Items[i].name)
            db.Items.InsertOnSubmit(Items[i]);
    }
    db.SubmitChanges();
}

我知道我也可以一个接一个地检查这些项目,并将不存在的项目插入到另一个列表中,然后在最后使用InsertAllOnSubmit()插入所有这些项目,但这也不能解决我的问题,因为我要检查数千个项目,我不想执行一千次查询来检查这些项目。是否有任何方法使用InsertAllOnSibmit的方式,只插入不存在的项目?

编辑:我没有义务使用Linq,如果有人知道更好的方法,通过存储过程或任何其他方式做到这一点,我真的很感谢你分享。

Linq InsertAllOnSubmit,如果不存在

一个查询找出需要插入的内容,然后在一些内存操作之后,您可以InsertAllOnSubmit:

using(MyDataContext db = new MyDataContext())
{
    var itemNames = Items.Select(i=>i.name).ToList();
    var itemNamesInDb = db.Items.Where(i=>itemNames.Contains(i.Name)).Select(i=>i.Name).ToList();
    var itemNamesNotInDb = new HashSet<string>(itemNames.Except(itemNamesInDb));
    var itemsNotInDb = Items.Where(i=>itemNamesNotInDb.Contains(i.name)).ToList();
    db.Items.InsertAllOnSubmit(itemsNotInDb);
    db.SubmitChanges();
}

不需要那么复杂这些名称似乎是主键。只需找出数据库中哪些名称属于要插入的项集。然后插入它们,不包括已经存在的。

var excludedNames = new HashSet<string>(
    from i in db.Items
    where Items.Select(item => item.Name).Contains(i.Name)
    select i.Name
);
db.Items.InsertAllOnSubmit(
    from i in Items
    where !excludedNames.Contains(i.Name)
    select i
);
db.SubmitChanges();

你可以尝试这样做:注意,并发性可能是一个问题,这样,我看到这正常工作的唯一方法是存储过程和阻塞策略到位,但如果想用L2SQL…

//1st db hit, to get the existing records, existing count never superior to toInsert count, 
//so it should not comsume a lot of memory
var existing = db.Items.Where(p => toInsert.Contains(p.Name)).ToList();
foreach (var input in toInsert)
{
    //fast in memory lookup
    if (existing.FirstOrDefault(p => p.Name== input) == null)
    {
       //insert the element
    }
}
//2nd db hit - submit to DB