我一直试图看一下我创建的一个方法中的缺陷,即更新(包括添加)一个对象,以及它是使用Entity Framework 6.0的子代。我已经查看了所有其他SO问题,但我无法看到我的错误。我有一个产品实体,可以有一个孩子的列表,这些孩子可以有一个孩子的列表。
这是我的产品实体
public partial class Product
{
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
public Product()
{
ProductSizes = new HashSet<ProductSize>();
}
public int Id { get; set; }
[Required]
[StringLength(100)]
public string Name { get; set; }
public int? PortfolioId { get; set; }
public bool IsActive { get; set; }
public int CreatedBy { get; set; }
public DateTime? CreatedDate { get; set; }
public int UpdatedBy { get; set; }
public DateTime? UpdatedDate { get; set; }
// This is a lookup entity that contains 1:1 relationship
public virtual Portfolio Portfolio { get; set; }
// This is a lookup entity that contains 1:1 relationship
public virtual User CreatedByUser { get; set; }
// This is a lookup entity that contains 1:1 relationship
public virtual User UpdatedByUser{ get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<ProductSize> ProductSizes { get; set; }
}
产品可以有很多孩子的ProductSize
public partial class ProductSize
{
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
public ProductSize()
{
ProductPackages = new HashSet<ProductPackage>();
}
public int Id { get; set; }
[ForeignKey("Product")]
public int ProductId { get; set; }
public int? CanSizeId { get; set; }
[StringLength(50)]
public string CanUPC { get; set; }
public int CreatedBy { get; set; }
public DateTime? CreatedDate { get; set; }
public int UpdatedBy { get; set; }
public DateTime? UpdatedDate { get; set; }
public bool IsActive { get; set; }
// This is a lookup entity that contains 1:1 relationship
public virtual CanSize CanSize { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<ProductPackage> ProductPackages { get; set; }
// Parent Product
public virtual Product Product { get; set; }
// This is a lookup entity that contains 1:1 relationship
public virtual User CreatedByUser{ get; set; }
// This is a lookup entity that contains 1:1 relationship
public virtual User UpdatedByUser{ get; set; }
}
ProductSize可以有很多ProductPackage
public partial class ProductPackage
{
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
public ProductPackage()
{
}
public int Id { get; set; }
[ForeignKey("ProductSize")]
public int ProductSizeId { get; set; }
public int PackageSizeId { get; set; }
[StringLength(50)]
public string CarrierCode { get; set; }
public int? SAPId { get; set; }
[StringLength(50)]
public string CaseUPCSupplierPack { get; set; }
public int CreatedBy { get; set; }
public DateTime? CreatedDate { get; set; }
public int UpdatedBy { get; set; }
public DateTime? UpdatedDate { get; set; }
public bool IsActive { get; set; }
// This is a lookup entity that contains 1:1 relationship
public virtual PackageSize PackageSize { get; set; }
// This is a lookup entity that contains 1:1 relationship
public virtual User CreatedByUser{ get; set; }
// Parent ProductSize
public virtual ProductSize ProductSize { get; set; }
// This is a lookup entity that contains 1:1 relationship
public virtual User UpdatedByUser{ get; set; }
}
我有一个接受产品并更新它的方法,并且如果需要,还可以在链中添加任何实体。
public void UpdateProduct(Product product, int userId)
{
var originalProduct = GetAllProductEntities().Where(a => a.Id == product.Id).SingleOrDefault();
var prouctEntry = _dbContext.Entry(originalProduct);
prouctEntry.CurrentValues.SetValues(newProduct);
foreach (var size in newProduct.ProductSizes)
{
var originalSize = originalProduct.ProductSizes.Where(a => a.Id == size.Id).SingleOrDefault();
if (originalSize != null)
{
var sizeEntry = _dbContext.Entry(originalSize);
sizeEntry.CurrentValues.SetValues(size);
}
else
{
// No -> It's a new child item -> Insert
size.Id = 0;
originalProduct.ProductSizes.Add(size);
}
foreach (var package in size.ProductPackages)
{
var originalPackage = originalSize.ProductPackages.Where(a => a.Id == package.Id).SingleOrDefault();
if (originalPackage != null)
{
var packageEntry = _dbContext.Entry(originalPackage);
packageEntry.CurrentValues.SetValues(package);
}
else
{
// No -> It's a new child item -> Insert
package.Id = 0;
originalSize.ProductPackages.Add(package);
}
}
}
_dbContext.SaveChanges();
}
调用SaveChanges()之后,我得到了这个System.InvalidOperationException
'操作失败:无法更改关系,因为一个或多个外键属性不可为空。当对关系进行更改时,相关的外键属性将设置为空值。如果外键不支持空值,则必须定义新关系,必须为外键属性分配另一个非空值,或者必须删除不相关的对象。'
如上所述,我已经阅读了大部分有关此问题的SO /问题,我相信这是我的模型的一个问题,但我很遗憾它可能是什么。此模型是从现有数据库生成的,因此如果我的模式出现问题,我也可以更改它。如果需要,我还可以提供更多代码片段。