Привет всем, столкнулся с ошибкой при добавлении новой сущности в базу данных. Ниже привожу код сущностей/код метода где создается сущность/код метода ответственного за добавление.
Сущности:
public sealed class Lot : Entity
{
[Required, DefaultValue(false)]
public bool IsActive { get; set; }
[Required, DefaultValue(false)]
public bool IsDelete { get; set; }
[Required, DefaultValue(false)]
public bool InCredit { get; set; }
[DefaultValue(1), Range(1, 10)]
public int PhaseNumber { get; set; }
[Required]
public decimal DesiredPrice { get; set; }
public Guid? AcceptedBetId { get; set; }
[Required]
public DateTime CreationDate { get; set; }
public DateTime ExpirationDateTime { get; set; }
[Required]
public string City { get; set; }
public User User { get; set; }
public Car Car { get; set; }
public ICollection<Bet> Bets { get; set; }
public Lot()
{
Bets = new List<Bet>();
}
}
public sealed class Bet : Entity
{
[Required, Range(0.0, double.MaxValue)]
public decimal Price { get; set; }
[Required]
public DateTime CreationDate { get; set; }
[Range(0, int.MaxValue)]
public int BetNumber { get; set; }
public Lot Lot { get; set; }
public User User { get; set; }
}
Участок кода где я создаю новую сущность, и вызываю метод сохранения:
Lot lot;
using (LotsManager lotsManager = new LotsManager())
{
lot = await lotsManager.GetLotAsync(model.LotId);
}
User user;
using (UserManager userManager = new UserManager())
{
user = await userManager.GetUserAsync(model.UserInfoId);
}
var bet = new Bet
{
Id = Guid.NewGuid(),
Price = model.Price,
CreationDate = DateTime.Now,
BetNumber = lastBetNumber + 1,
Lot = lot,
User = user
};
await _betsManager.SaveBetAsync(bet);
Метод который ответственен а добавление данных в БД.
protected async Task Save<T>(T entity) where T : Entity
{
using (var dbContextTransaction = _context.Database.BeginTransaction())
{
try
{
var dbEntity = await _context.Set<T>().SingleOrDefaultAsync(x => x.Id == entity.Id);
_context.Set<T>().Attach(entity);
_context.Entry(entity).State = dbEntity != null ? EntityState.Modified : EntityState.Added;
await _context.SaveChangesAsync();
dbContextTransaction?.Commit();
}
catch (DbEntityValidationException ex)
{
dbContextTransaction?.Rollback();
var error = ex.EntityValidationErrors.First().ValidationErrors.First();
throw new InvalidModelException(error.ErrorMessage);
}
catch (Exception ex)
{
dbContextTransaction?.Rollback();
throw new InvalidDbOperationException(ex.Message);
}
}
}
Собственно сом код ошибки. Она возникает на строке (_context.Set().Attach(entity)).
Attaching an entity of type 'WebCar.Domain.Entities.Lot' failed because another entity of the same type already has the same primary key value. This can happen when using the 'Attach' method or setting the state of an entity to 'Unchanged' or 'Modified' if any entities in the graph have conflicting key values. This may be because some entities are new and have not yet received database-generated key values. In this case use the 'Add' method or the 'Added' entity state to track the graph and then set the state of non-new entities to 'Unchanged' or 'Modified' as appropriate.
Я пробовал использовать разные приемы, но ничего не получилось
_context.Set<T>().Attach(entity);
_context.Entry(entity).State = EntityState.Unchanged;
or
_context.Entry(entity).State = EntityState.Unchanged;
Спасибо всем кто откликнется. Сам я джун, так что особо не судите.
Проблема кроется в методе:
protected async Task Save<T>(T entity) where T : Entity
{
using (var dbContextTransaction = _context.Database.BeginTransaction())
{
try
{
var dbEntity = await _context
.Set<T>().SingleOrDefaultAsync(x => x.Id == entity.Id);
_context.Set<T>().Attach(entity);
_context.Entry(entity).State =
dbEntity != null
? EntityState.Modified
: EntityState.Added;
await _context.SaveChangesAsync();
dbContextTransaction?.Commit();
}
catch (DbEntityValidationException ex) { /* ... */ }
catch (Exception ex) { /* ... */ }
}
}
entity
, передаваемый через параметр в метод. dbEntity
primary key
, которые нужно отслеживать, от этого и падает ошибка.Как исправить:
dbEntity
использовать AsNoTracking
, метод AsNoTracking()
применяется к набору IQueryable
, это значит что Entity Framework не будет отслеживать изменения полученных объектов.EntityState.Modified
если был или EntityState.Added
если не было.Айфон мало держит заряд, разбираемся с проблемой вместе с AppLab
Перевод документов на английский язык: Важность и ключевые аспекты
В общем, на работе стоит русская Windows 7, а дома английский Windows 10, так вот на работе с кодировками проблем нету, а дома какие-то кракозябры
Как передать в MatchEvaluator доппараметры
Есть несколько checkbox'ов с тремя состояниями: включено, исключено, не установлено