任何使EntityFramework的SaveChanges()方法跳过条目的方法如果它已经存在?

时间:2016-12-06 18:51:38

标签: 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的记录时,有没有办法告诉框架执行Name?这总是抛出一个重复的异常,我希望它只是忽略它并继续前进。

编辑: 我已将多个线程的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;
    }
}

但问题仍然存在。

1 个答案:

答案 0 :(得分:1)

为什么不运行dbContext.Get.Any(x =&gt; x.Name == tag.Name)并跳过根据它添加新标签?

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

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

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