c# - 有什么方法可以使 EntityFramework 的 SaveChanges() 方法跳过一个条目(如果它已经存在)?

标签 c# mysql .net entity-framework innodb

我的应用程序中有一个 Tag 模型:

public class Tag
{
    public Tag() { }
    public Tag(string t)
    {
        Name = t;
        Pictures = new List<Picture>();
    }

    public int Id { get; set; }
    [MaxLength(96), Index(IsUnique = true)]
    public string Name { get; set; }

    public virtual List<Picture> Pictures { get; set; }

}

当具有相同名称 的记录已经存在时,是否有任何方式告诉框架执行ON DUPLICATE DO NOTHING?这总是会引发重复异常,我希望它忽略它并继续。

编辑:我已经将许多线程中的 EF 代码更改为:

async Task SaveQueue()
{
    for (;;)
    {
        try
        {
            await Task.Delay(7500);
            dbUploadProgress.Visibility = Visibility.Visible;
            dbUploadProgress.Value = 0;
            var q = new ObservableCollection<Picture>(manager.Queue.ToList().AsEnumerable());
            manager.Queue.Clear();
            var imgcount = q.Count();
            for (int i = 0; i < imgcount; i++)
            {
                using (var pc = new PicsContext())
                {
                    var tags = q[i].GetTags();
                    pc.Sites.Attach(q[i].Site); // I'm actually not sure how to use this. 
                    var curUrl = q[i].Url;
                    if (pc.Pictures.FirstOrDefault(o => o.Url == curUrl) != null)
                        continue;
                    foreach (var t in tags)
                    {
                        var tag = pc.Tags.Where(o => o.Name == t).FirstOrDefault();
                        if (tag == null)
                        {
                            tag = new ViewModel.Tag(t);
                        }
                        q[i].Tags.Add(tag);
                        try
                        {
                            await pc.SaveChangesAsync();
                        }
                        catch { }
                    }
                    pc.Pictures.Add(q[i]);
                    try
                    {
                        await pc.SaveChangesAsync();
                    }
                    catch { }
                    dbUploadProgress.Value = (i + 1) / (double)imgcount;
                }
            }
            q.Clear();
            MainWindow.AddLog(string.Format("Saved {0} pictures.", imgcount));
            dbUploadProgress.Visibility = Visibility.Collapsed;
            await Task.Delay(1500);
        }
        catch { }
        if (isStopped)
            break;
    }
}

但问题仍然存在。

最佳答案

为什么不运行 dbContext.Get.Any(x=>x.Name==tag.Name) 并跳过添加基于它的新标签?

我认为问题在于您的队列异步处理消息,因此您可以有 2 个线程尝试插入相同的标记,因为检查是否存在逻辑在插入之前运行。

您可以通过一次只处理 1 个队列消息(让一个工作线程/线程处理队列)来解决这个问题。

或者另一种解决方法可能是隔离保存在 try catch 中的标签并正确处理重复的异常(从 db 重新加载标签并在将其设置在新对象上时使用该标签)。

关于c# - 有什么方法可以使 EntityFramework 的 SaveChanges() 方法跳过一个条目(如果它已经存在)?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41002703/

相关文章:

c# - 在 C# 中操作密封类型

c# - 领域驱动设计中的存储库和聚合根

php - MySQL:我需要根据相同的条件将多行中的相同列名拉到单个查询中

c# - InternalsVisibleTo、Signing 和 Unit tests,如何落地?

c# - 创建证书时未处理的加密异常

c# - 我如何解析一个dtd文件

mysql - 如何在 knex 中使用 'and' 和 'on' 连接条件

php - 循环jquery block ui

c# - 使用 DeflateStream 读取与预期大小不匹配

C# 关闭数据库连接