【问题标题】:Prevent duplicates when inserting插入时防止重复
【发布时间】:2012-08-30 23:15:10
【问题描述】:

我有一些标签需要插入到标签数据库中。 Tag 数据库只有一列“tag”,它也是主键。这是在插入时防止重复的技巧。

现在是代码和问题。

foreach (string tagval in tagarray)
{
    try
    {
        var tag = new Tag
        {
            Tag1 = tagval
        };
        db.AddToTags(tag);
    }
    catch
    {
    }
}
db.SaveChanges();

这种方法的问题是在调用SaveChanges()之后如果早早发现重复,程序就存在而不保存其他标签。如果我在每次添加到表后都调用SaveChanges(),程序将变得低效并且需要进行大量调用。即使在较早的插入失败后如何继续插入?

也欢迎使用替代解决方案。

【问题讨论】:

    标签: c# .net linq entity-framework duplicates


    【解决方案1】:

    您需要在此处更改几件事。首先,您最好先从自己的列表中删除重复项,然后再通过调用列表中的.Distinct 来插入数据库。

    此外,这里不需要 try catch,您应该在插入之前检查数据库中已有的内容。试试这个:

    List<string> uniqueItems = tagarray
        .Distinct()
        .Where(x => !db.Tags.Contains(x))
        .ToList();
    
    foreach (string uniqueItem in uniqueItems)
    {
        var tag = new Tag
        {
            Tag1 = tagval
        };
        db.AddToTags(tag);   
    }
    
    db.SaveChanges();
    

    【讨论】:

    • Tag数据库条目很多,几天后可能会达到一百万,检查效率会不会低?
    • 如果我没记错,并且 EF 的工作方式与 NHibernate 相同,那么它应该执行 JOIN,所以它应该是一个查询。在输出窗口中检查一下,我有兴趣看看:)。
    【解决方案2】:

    使用 Entity Framework 和 ObjectContext 派生,您可以做这样的事情。

    foreach (var newTag in tagarray.Select(t => 
                   new Tag { Tag1 = t }).Except(db.Tags))
    {
        db.Tags.AddObject(newTag);
    }
    
    try
    {
        db.SaveChanges(SaveOptions.AcceptAllChangesAfterSave);
    }
    catch (OptimisitcConcurrencyException)
    {
        db.Refresh(RefreshMode.StoreWins, db.Tags);
        foreach (var newTag in tagarray.Select(t => 
                       new Tag { Tag1 = t }).Except(db.Tags))
        {
            db.Tags.AddObject(newTag);
        }
        db.SaveChanges();
    }
    

    【讨论】:

    • 它不是 linq to sql,显然 dataContext 的使用造成了混乱。它的实体框架。
    • 我发现混淆是由 linq-to-sql 标记引起的,但我发现它现在已被实体框架标记所取代。
    【解决方案3】:
    foreach (string tagval in tagarray)
    {
        try
        {
            var tag = new Tag
            {
                Tag1 = tagval
            };
          if(Tags.Where(e =>tag ) != null)
            {
            dataContext.AddToTags(tag);
            }
        }
        catch
        {
        }
    }
    dataContext.SaveChanges();
    

    【讨论】:

    • Tags.Where(e =>tag ) 搜索标签中是否存在具有相同值的任何可能标签,如果它发现任何出现它跳过 dataContext.AddToTags(tag);并防止重复值
    • 效率怎么样?如果数据库中有很多元组,会不会效率低下?
    • 您需要使用事务,否则在并发边缘情况下可能会失败。
    • 我有这个解决方案我认为它会有很好的效率
    猜你喜欢
    • 2015-08-07
    • 2016-02-19
    • 1970-01-01
    • 1970-01-01
    • 2020-05-31
    • 2021-09-25
    • 2018-04-11
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多