Я получил проблема, когда я пытаюсь использовать метод AddTimeSeriesDefinition(TimeSeries series)
или AddTimeSeriesMetaData(TimeSeriesMetaData tsData)
внутри Parallel.ForEach()
EF6 Невозможно вставить дубликат ключа - я не могу найти причину этого исключения
Я борюсь с этим в течение нескольких часов, и я не могу поверить, что я не могу найти никакого решения или даже теоретической причины.
Внутри моего класса Data
, который содержит мой контекст дб DBEntity db = new DBEntity()
У меня AddTimeSeriesDefinition(TimeSeries series)
и AddTimeSeriesMetaData()
методы:
public class Data : IDisposable
{
private DBEntity db;
public Data()
{
db = new DBEntity();
}
public TimeSeries AddTimeSeriesDefinition(TimeSeries series)
{
var timeSeries = db.TimeSeries.Where(ts => ts.Key1 == series.Key1)
.Where(ts => ts.Key2 == series.Key2)
.Where(ts => ts.Key3 == series.Key3)
.FirstOrDefault();
if (timeSeries == null)
{
timeSeries = db.TimeSeries.Add(series);
db.SaveChanges();
}
return timeSeries;
}
public void AddTimeSeriesMetaData(TimeSeriesMetaData tsData)
{
var tsd = db.TimeSeriesMetaData.Where(ts => ts.Key1 == tsData.Key1)
.Where(ts => ts.Key2== tsData.Key2)
.FirstOrDefault();
if (tsd == null)
db.TimeSeriesMetaData.Add(tsData);
else
tsd.Value = tsData.Value;
try
{
db.SaveChanges();
}
catch (Exception ex)
{
Log.Error($"Error occurred (...) Key1:{tsData.Key1} Key2:{tsData.Key2}", ex);
}
}
Dispose()
{...}
}
Однако, когда я использую их в своей основной класс, например:
private MainClass
{
Data DB { get { value = new Data() } }
...
Parallel.ForEach(// arguments)
{
...
using(var db = DB)
{
db.AddTimeSeriesDefinition(timeSeries);
}
...
}
}
иногда, полностью беспорядочно сбой в линии
db.SaveChanges();
за исключением:
Violation of PRIMARY KEY constraint 'PK_TimeSeriesMetaDatas'. Cannot insert duplicate key in object 'dbo.TimeSeriesMetaData'. The duplicate key value is ("Key1", "Key2"). The statement has been terminated.
Например мой TimeSeriesMetaData
EF класс:
[Table("TimeSeriesMetaData")]
public partial class TimeSeriesMetaData
{
[Key]
[Column(Order = 0)]
[DatabaseGenerated(DatabaseGeneratedOption.None)]
public string Key1 { get; set; }
[Key]
[Column(Order = 1)]
public string Key2 { get; set; }
[Required]
public string Key3 { get; set; }
}
Я прочитал, что создание Entity Framework
DBContext
каждый раз для каждой операции должно быть также потокобезопасно. Что может быть причиной этой проблемы, если я всегда проверял, существует ли запись?
Буду признателен за любую помощь.
Спасибо. Я считаю, что это решение, чтобы добавить lock() {} в эти методы. Кажется, что сейчас работает без каких-либо проблем, насколько я смог проверить за 1 час. – Wiktor