我有方法AddOrUpdateFruitMetaData
,它应该在FruitMetaData
表中添加或更新记录。
不幸的是,我不断收到错误:
Violation of PRIMARY KEY constraint 'PK_FruitMetaData'. Cannot insert duplicate key in object 'dbo.FruitMetaData'. The duplicate key value is (0, COLOR). The statement has been terminated.
即使我之前试图找到现有记录,这怎么可能呢?
同时使用AddOrUpdate()
而不是System.Data.Entity.Migrations
中的Add()
对我没有帮助。
调用堆栈看起来:
在Parallel.ForEach
的主要课程中,多个for
循环看起来像这样:
Parallel.ForEach(args)
{
for(something)
{
var fruit = new Fruit();
fruit.FruitId = uniqueId;
UpdateOrCreateFruitMetaData(fruit, "Color", "Blue")
}
}
我正在呼叫方法:
private void UpdateOrCreateFruitMetaData(Fruit fruit, string metaType, string value)
{
var fruitMetaData = new FruitMetaData();
fruitMetaData.FruitId = fruit.FruitId;
fruitMetaData.MetaType = metaType;
fruitMetaData.Value = value;
using (var db = Context.DB)
{
db.AddOrUpdateFruitMetaData(fruitMetaData);
}
}
该方法使用Context.DB
,它是包含new DBEntity()
的对象,也是Dispose()。所以每次都会处理我的实体上下文。
然后我调用下一个方法AddOrUpdateFruitMetaData()
:
AddOrUpdateFruitMetaData(FruitMetaData fruitMetaData)
{
lock (thisLock)
{
try
{
var fmd = db.FruitMetaData.Where(x => x.FruitId == fruitMetaData.FruitId)
.Where(x => x.MetaType == fruitMetaData.MetaType)
.FirstOrDefault();
if (fmd == null)
db.FruitMetaData.Add(fruitMetaData);
else
fmd.Value = fruitMetaData.Value;
db.SaveChanges();
}
catch (Exception ex)
{
Log.Error($"AddOrUpdateFruitMetaData. FruitId:{fruitMetaData.FruitId} MetaType:{fruitMetaData.MetaType}", ex);
}
}
}
[编辑]解释using (var db = Context.DB)
:
我的Context
类包含DbData DB
属性,如下所示:
public DbData DB
{
get { return new DbData(); }
}
DbData
类看起来像这样:
public class DbData : IDisposable
{
private DBEntity db;
public DbData()
{
db = new FruitDBEntity();
}
// This class contains that problematic method
AddOrUpdateFruitMetaData(FruitMetaData fruitMetaData)(...)
}
因此,每次我获得Context.DB属性时,我实际上都在创建新的实体上下文。