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

Any way to make EntityFramework's SaveChanges() method skip an entry if it already exists?

我的应用程序中有一个 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; }

}

当具有相同 Name 的记录已经存在时,是否有任何方法可以告诉框架执行 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 个队列消息(让一个 worker/thread 处理队列)来解决问题。

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