假设我有这种情况。
这是我的表(ParentID列包含LocationID的值):
示例:
LocationID LocationCode ParentID
Row 1 1 Code_Parent NULL
Row 2 2 Code_Child 1 //ID of row 1
结构:
CREATE TABLE [dbo].[Location]
(
[LocationID] [int] IDENTITY(1,1) NOT NULL,
[ParentID] [int] NULL,
[LocationCode] [varchar](20) NOT NULL,
[LocationName] [nvarchar](125) NULL,
CONSTRAINT [PK_Location_LocationID]
PRIMARY KEY CLUSTERED ([LocationID] ASC)
)
ALTER TABLE [dbo].[Location] WITH CHECK
ADD CONSTRAINT [FK_Location_Location_ParentID]
FOREIGN KEY([ParentID]) REFERENCES [dbo].[Location] ([LocationID])
GO
ALTER TABLE [dbo].[Location] CHECK CONSTRAINT [FK_Location_Location_ParentID]
GO
Entity Framework 6.0:
EF是从PowerTool生成的,以下是类:
public LocationMap()
{
// Primary Key
this.HasKey(t => t.LocationID);
// Properties
this.Property(t => t.LocationCode)
.IsRequired()
.HasMaxLength(20);
this.Property(t => t.LocationName)
.HasMaxLength(125);
// Table & Column Mappings
this.ToTable("Location");
this.Property(t => t.LocationID).HasColumnName("LocationID");
this.Property(t => t.ParentID).HasColumnName("ParentID");
this.Property(t => t.LocationCode).HasColumnName("LocationCode");
this.Property(t => t.LocationName).HasColumnName("LocationName");
// Relationships
this.HasOptional(t => t.Location2)
.WithMany(t => t.Location1)
.HasForeignKey(d => d.ParentID);
}
实现:
MD_Location1
是儿童列表MD_Location2
是父位置代码:
IUnitOfWorkAsync _unitOfWorkAsync = new UnitOfWork(dataContext); //it worked
// 1. add parent location
MD_Location locParent = new MD_Location()
{
ParentID = null,
LocationName = "Parent 1",
ObjectState = ObjectState.Added
};
// 2. add 2 child locations
MD_Location locChild1 = new MD_Location()
{
ParentID = locParent.LocationID, // is code right?
LocationName = "Child 1",
ObjectState = ObjectState.Added
};
locChild1.MD_Location2 = locParent; // I tried but it does not work
locParent.MD_Location1.Add(locChild1); // I also tried but it not work either
MD_Location locChild2 = new MD_Location()
{
ParentID = locParent.LocationID, // is code right?
LocationName = "Child 2",
ObjectState = ObjectState.Added
};
locChild2.MD_Location2 = locParent; // I tried but it does not work
locParent.MD_Location1.Add(locChild2); // I also tried but it not work either
_unitOfWorkAsync.Repository<MD_Location>().Insert(location);
_unitOfWorkAsync.SaveChanges();
但是会发生错误:
附加“位置”类型的实体失败,因为同一类型的另一个实体已具有相同的主键值。
我怎么能解决这个问题?
请告知。
非常感谢。
答案 0 :(得分:1)
在将该对象保存到数据库之前从locParent.LocationID分配parrentId并且如果您在该列上启用了标识,那么LocationId
属性将保持值0并且EF不知道ParentId需要从auto附加生成了locParent对象的Id。
MD_Location locChild2 = new MD_Location()
{
//ParentID = locParent.LocationID, //is not correct
LocationName = "Child 2",
ObjectState = ObjectState.Added
};
相反,您应该使用导航属性,以便EF可以理解需要首先保存locParent对象,并且需要将其自动生成的Id保存在locChild2的ParentId列中。
MD_Location locChild2 = new MD_Location()
{
MD_Location2 = locParent,
LocationName = "Child 2",
ObjectState = ObjectState.Added
};
答案 1 :(得分:1)
这是一种没有任何噪音的简化工作解决方案:
模型定义:
public class Model1 : DbContext
{
public Model1()
: base( "name=Model1" )
{
}
protected override void OnModelCreating( DbModelBuilder modelBuilder )
{
base.OnModelCreating( modelBuilder );
var location = modelBuilder.Entity<Location>();
// location.ToTable( nameof( Location ) );
location.HasKey( e => e.Id );
location.Property( e => e.Code )
.IsRequired()
.HasMaxLength( 20 );
location.Property( e => e.Name )
.HasMaxLength( 125 );
location.HasOptional( e => e.Parent )
.WithMany( e => e.Children )
.HasForeignKey( e => e.ParentId )
.WillCascadeOnDelete( false );
}
public virtual DbSet<Location> Locations { get; set; }
}
public class Location
{
public int Id { get; set; }
public string Code { get; set; }
public string Name { get; set; }
public int? ParentId { get; set; }
public virtual Location Parent { get; set; }
public virtual ICollection<Location> Children { get; set; }
}
用例
using ( var db = new Model1() )
{
var parent_location = new Location
{
Code = "Code_Parent",
};
var child_location = new Location
{
Code = "Code_Child",
Parent = parent_location,
};
db.Locations.Add( child_location );
db.SaveChanges();
}
主要区别在于,我将实例附加到导航属性(Parent = parent_location
),EF将执行其余操作,并且还会处理我未明确添加到位置集合的父位置。