我用。net core EF存储库模式与postgresql和我在ChangeStatusOfShipment方法中得到错误:
注意:Id不是packages表中的PK。条形码列是包裹表中的PK
{
“ErrorMessage:“无法跟踪实体类型‘Packages’的实例,因为已在跟踪另一个具有{'Id'}相同键值的实例。附加现有实体时,请确保仅附加一个具有给定键值的实体实例。请考虑使用'DbContextOptions Builder.EnableSensiveDatalogg'查看冲突键值。”
}
PackageOrBag packageOrBag = await DecideShipmentType(delivery.Barcode);
if (packageOrBag == PackageOrBag.Bag)
{
BagDTO bagDTO = await CreateBagDTO(delivery);
shipmentDTO = bagDTO;
} else {
PackageDTO packageDTO = await CreatePackageDTO(delivery);
shipmentDTO = packageDTO;
}
await ChangeStatusOfShipment(shipmentDTO, packageOrBag, Status.Loaded);
if (shipmentDTO.DeliveryPoint == route.DeliveryPoint)
{
status = await DecideShipment(packageOrBag, route.DeliveryPoint) == true ? (int)Status.UnLoaded : (int)Status.Loaded;
if (status == (int)Status.UnLoaded)
{
await ChangeStatusOfShipment(shipmentDTO, packageOrBag, Status.UnLoaded);
}
else
bagsToBeLoaded.Add(shipmentDTO);
}
public async Task<BagDTO> CreateBagDTO(Delivery delivery)
{
Bags bag = (await _bagRepository.GetWhere(i => i.Barcode == delivery.Barcode)).FirstOrDefault();
BagDTO bagDTO = new BagDTO() {
Id = bag.Id,
Barcode = bag.Barcode,
DeliveryPoint = bag.DeliveryPoint,
State = bag.State
};
bagDTO.Packages = new List<PackageDTO>();
var packagesIntoBags = (await _packagesToBagRepository.GetWhere(i => i.BagBarcode == delivery.Barcode)).ToList();
foreach (var packageIntoBag in packagesIntoBags)
{
Packages package = (await _packageRepository.GetWhere(i => i.Barcode == packageIntoBag.Barcode)).FirstOrDefault();
PackageDTO packageDTO = new PackageDTO()
{
Barcode = package.Barcode,
DeliveryPoint = package.DeliveryPoint,
Id = package.Id,
State = package.State,
Weight = package.Weight
};
bagDTO.Packages.Add(packageDTO);
}
return bagDTO;
}
public async Task<PackageDTO> CreatePackageDTO(Delivery delivery)
{
Packages package = (await _packageRepository.GetWhere(i => i.Barcode == delivery.Barcode)).FirstOrDefault();
return new PackageDTO()
{
Barcode = package.Barcode,
DeliveryPoint = package.DeliveryPoint,
Id = package.Id,
State = package.State,
Weight = package.Weight
};
}
public async Task ChangeStatusOfShipment(ShipmentDTO shipmentDTO, PackageOrBag packageOrBag, Status status)
{
if (packageOrBag == PackageOrBag.Bag)
{
shipmentDTO.State = (int)status;
BagDTO bagDTO = (BagDTO)shipmentDTO;
Bags bag = new Bags() {
Id = bagDTO.Id,
Barcode = bagDTO.Barcode,
State= bagDTO.State,
DeliveryPoint = bagDTO.DeliveryPoint
};
await _bagRepository.Update(bag);
if (status == Status.Loaded)
{
var packagesInBags = await _packagesToBagRepository.GetWhere(i => i.BagBarcode == shipmentDTO.Barcode);
foreach (var packageInBag in bagDTO.Packages)
{
packageInBag.State = (int)status;
var package = (await _packageRepository.GetWhere(i => i.Barcode == packageInBag.Barcode)).FirstOrDefault();
package.State = (int)status;
await _packageRepository.Update(package);
}
}
}
else
{
shipmentDTO.State = (int)status;
PackageDTO packageDTO = (PackageDTO)shipmentDTO;
var package = (await _packageRepository.GetWhere(i => i.Barcode == packageDTO.Barcode)).FirstOrDefault();
package.State = (int)status;
await _packageRepository.Update(package);
}
}
public class Repository<T> : IRepository<T> where T : BaseEntity
{
#region Fields
protected FleetManagementContext Context;
#endregion
public Repository(FleetManagementContext context)
{
Context = context;
}
#region Public Methods
public Task<T> FirstOrDefault(Expression<Func<T, bool>> predicate)
=> Context.Set<T>().FirstOrDefaultAsync(predicate);
public async Task Add(T entity)
{
await Context.Set<T>().AddAsync(entity);
await Context.SaveChangesAsync();
}
public Task Update(T entity)
{
Context.Entry(entity).State = EntityState.Modified;
return Context.SaveChangesAsync();
}
public Task Remove(T entity)
{
Context.Set<T>().Remove(entity);
return Context.SaveChangesAsync();
}
public async Task<IEnumerable<T>> GetAll()
{
return await Context.Set<T>().ToListAsync();
}
public async Task<IEnumerable<T>> GetWhere(Expression<Func<T, bool>> predicate)
{
return await Context.Set<T>().Where(predicate).ToListAsync();
}
public Task<int> CountAll() => Context.Set<T>().CountAsync();
public Task<int> CountWhere(Expression<Func<T, bool>> predicate)
=> Context.Set<T>().CountAsync(predicate);
#endregion
}
services.AddEntityFrameworkNpgsql().AddDbContext<FleetManagementContext>(opt =>
opt.UseNpgsql(Configuration.GetConnectionString("DefaultConnection")).UseQueryTrackingBehavior(QueryTrackingBehavior.NoTracking));