我有表:供应商和品牌以及基本抽象类
public abstract class Entity<TEntity, TKeyType> : IEntity<TEntity, TKeyType>
where TEntity : class
{
[Key]
public virtual TKeyType ID { get; set; }
public virtual bool IsDeleted { get; set; }
#region Equals
public virtual bool Equals(Entity<TEntity, TKeyType> other)
{
if (ReferenceEquals(this, other))
return true;
if (other == null || !(other is TEntity))
return false;
return ID.Equals(other.ID);
}
public override bool Equals(object obj)
{
var compareTo = obj as Entity<TEntity, TKeyType>;
return Equals(compareTo);
}
public override int GetHashCode()
{
return ID.GetHashCode();
}
#endregion
}
实体:
public partial class Vendor : Entity<Vendor, long>
{
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
public Vendor()
{
Brand = new HashSet<Brand>();
}
[Required]
[StringLength(32)]
public string Name { get; set; }
public Guid Guid { get; set; }
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
public virtual ICollection<Brand> Brand { get; set; }
}
和
public partial class Brand : Entity<Brand, long>
{
[System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
public Brand()
{
SubBrand = new HashSet<SubBrand>();
}
[Required]
[StringLength(64)]
public string Name { get; set; }
public Guid Guid { get; set; }
public long VendorID { get; set; }
public virtual Vendor Vendor { get; set; }
}
ODMSDBContext:
public partial class ODMSDBContext : DbContext
{
public ODMSDBContext() : base("name=ODMSConnection") { }
public virtual DbSet<Vendor> Vendor { get; set; }
public virtual DbSet<Brand> Brand { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Brand>()
.Property(e => e.ExtraCode)
.IsUnicode(false);
modelBuilder.Entity<Brand>()
.Property(e => e.Name)
.IsUnicode(false);
modelBuilder.Entity<Brand>()
.HasMany(e => e.SubBrand)
.WithRequired(e => e.Brand)
.HasForeignKey(e => e.BrandID)
.WillCascadeOnDelete(false);
modelBuilder.Entity<Vendor>()
.Property(e => e.Name)
.IsUnicode(false);
modelBuilder.Entity<Vendor>()
.HasMany(e => e.Brand)
.WithRequired(e => e.Vendor)
.HasForeignKey(e => e.VendorID)
.WillCascadeOnDelete(false);
}
}
服务中的存在方法 - 创建
public override void Create(IEnumerable<EntityModel> models)
{
var entities = new List<Brand>();
foreach (var model in models)
{
var entityModel = model as BrandModel;
var entity = new Brand
{
Guid = entityModel.Guid,
VendorID = entityModel.VendorID,
Name = entityModel.Name,
SortOrder = entityModel.SortOrder,
ExtraCode = entityModel.ExtraCode
};
entities.Add(entity);
}
_repository.Create(entities);
_repository.Save();
}
来自Repository(_repository)
的代码示例public class EntityRepository<TEntity, TKeyType> : IEntityRepository<ODMSDBContext, TEntity, TKeyType>
where TEntity : class, IEntity<TEntity, TKeyType>
{
private readonly ODMSDBContext _context;
private DbSet<TEntity> DbSet => _context.Set<TEntity>();
public EntityRepository(ODMSDBContext context)
{
_context = context;
}
...
public void Create(IEnumerable<TEntity> entities)
{
DbSet.AddRange(entities);
}
public void Save()
{
_context.SaveChanges();
transaction.Commit();
}
}
}
关于保存我收到错误:
保存前我检查了品牌。最重要的供应商是null,但VendorID已填满。 我尝试在方法Create 中的Service中添加它抛出异常:&#39; System.InvalidOperationException&#39;在EntityFramework.dll
中附加信息:操作失败:关系不能是&gt;因为一个或多个外键属性不可为空而更改。当对关系进行更改时,相关的外键属性将设置为空值。如果外键不支持空值,则必须定义新关系,必须为外键属性分配另一个非空值,或者必须删除不相关的对象。
Vendor = _vendorRepository.GetById(entityModel.VendorID)
但在供应商字段的AddRange数据消失后%)
UPD。我创建了一个描述奇怪行为的小视频 - http://screencast.com/t/RI32v4gu
答案 0 :(得分:0)
我没有看到Key数据注释,或者您在Fluent API中设置了实际的键。
尝试更改modelBuilder覆盖以在每个实体上显式设置外键。
public partial class ODMSDBContext : DbContext
{
public ODMSDBContext() : base("name=ODMSConnection") { }
public virtual DbSet<Vendor> Vendor { get; set; }
public virtual DbSet<Brand> Brand { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Brand>()
.Property(e => e.ExtraCode)
.IsUnicode(false);
modelBuilder.Entity<Brand>()
.Property(e => e.Name)
.IsUnicode(false);
modelBuilder.Entity<Brand>()
.HasMany(e => e.SubBrand)
.WithRequired(e => e.Brand)
.HasForeignKey(e=>e.ID)
.WillCascadeOnDelete(false);
modelBuilder.Entity<Vendor>()
.Property(e => e.Name)
.IsUnicode(false);
modelBuilder.Entity<Vendor>()
.HasMany(e => e.Brand)
.WithRequired(e => e.Vendor)
.HasForeignKey(e=>e.ID)
.WillCascadeOnDelete(false);
}
}
答案 1 :(得分:0)
我需要为浪费你的时间而感到抱歉。我没有复制我的抽象类实体的所有代码,这就是你无法帮助我的原因。在抽象类Entity中,我实现了用于比较的基本方法。
当我尝试向供应商添加新品牌时,所有品牌中的字段ID等于0.此值与HashSet中存在的比较,借助我的比较基本方法,并且未添加新记录,因为Brand此列表中确实存在ID = 0。
我评论了比较的基本方法,一切正常:)
PS。请感谢@ grek40;)