Joh*_*ohn 14 c# sql entity-framework entity-framework-6
所以这里有几个类似的问题,但我仍然有问题确定我在简化场景中究竟缺少了什么.
假设我有以下表格,巧妙地以自己的名字命名:
'JohnsParentTable' (Id, Description)
'JohnsChildTable' (Id, JohnsParentTableId, Description)
Run Code Online (Sandbox Code Playgroud)
结果类看起来像这样
public class JohnsParentTable
{
public int Id { get; set; }
public string Description { get; set; }
public virtual ICollection<JohnsChildTable> JohnsChildTable { get; set; }
public JohnsParentTable()
{
JohnsChildTable = new List<JohnsChildTable>();
}
}
internal class JohnsParentTableConfiguration : EntityTypeConfiguration<JohnsParentTable>
{
public JohnsParentTableConfiguration()
{
ToTable("dbo.JohnsParentTable");
HasKey(x => x.Id);
Property(x => x.Id).HasColumnName("Id").IsRequired().HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
Property(x => x.Description).HasColumnName("Description").IsRequired().HasMaxLength(50);
}
}
public class JohnsChildTable
{
public int Id { get; set; }
public string Description { get; set; }
public int JohnsParentTableId { get; set; }
public JohnsParentTable JohnsParentTable { get; set; }
}
internal class JohnsChildTableConfiguration : EntityTypeConfiguration<JohnsChildTable>
{
public JohnsChildTableConfiguration()
{
ToTable("dbo.JohnsChildTable");
HasKey(x => x.Id);
Property(x => x.Id).HasColumnName("Id").IsRequired().HasDatabaseGeneratedOption(DatabaseGeneratedOption.Identity);
Property(x => x.Description).HasColumnName("Description").IsRequired().HasMaxLength(50);
HasRequired(a => a.JohnsParentTable).WithMany(c => c.JohnsChildTable).HasForeignKey(a => a.JohnsParentTableId);
}
}
Run Code Online (Sandbox Code Playgroud)
在数据库中,我在父表中有一行,Id为1,子表中有两行绑定到该父表.如果我这样做:
var parent = db.JohnsParentTable.FirstOrDefault(a => a.Id == 1)
Run Code Online (Sandbox Code Playgroud)
正确填充对象.但是,如果我尝试删除此行:
var parent = new Data.Models.JohnsParentTable() { Id = 1 };
db.JohnsParentTable.Attach(parent);
db.JohnsParentTable.Remove(parent);
db.SaveChanges();
Run Code Online (Sandbox Code Playgroud)
实体框架尝试执行以下操作:
DELETE [dbo].[JohnsParentTable]
WHERE ([Id] = @0)
-- @0: '1' (Type = Int32)
-- Executing at 1/23/2014 10:34:01 AM -06:00
-- Failed in 103 ms with error: The DELETE statement conflicted with the REFERENCE constraint "FK_JohnsChildTable_JohnsParentTable". The conflict occurred in database "mydatabase", table "dbo.JohnsChildTable", column 'JohnsParentTableId'.
The statement has been terminated.
Run Code Online (Sandbox Code Playgroud)
那么我的问题是我错过了什么以确保实体框架知道它必须在删除父项之前删除'JohnsChildTable'行?
Jah*_*han 17
我认为最好覆盖OnModelCreating方法并添加此代码.
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<JohnsChildTable>()
.HasRequired(t=>t.JohnsParentTable)
.WithMany(t=>t.JohnsChildTables)
.HasForeignKey(d=>d.JohnsParentTableId)
.WillCascadeOnDelete(true);
base.OnModelCreating(modelBuilder);
}
Run Code Online (Sandbox Code Playgroud)
我设置为true WillCascadeOnDelete(true)
Pet*_*sen 12
这取决于您是希望实体框架删除子项,还是希望数据库处理它.
如果希望EF为所有子项生成delete语句并在删除父项之前执行这些语句,则必须先将所有子项加载到内存中.
所以你不能简单地只用填充的密钥创建一个"虚拟"实体,并期望删除子项.
为此,您必须让数据库处理删除.
子表上的外键必须启用级联删除.如果是这种情况,Entity Framework只为父级创建一个delete语句,数据库也知道删除子级.
如果需要关系,实体框架会创建一个默认启用级联删除的外键,就像您的情况一样.(外键不能为空).
如果您自己创建了数据库,则必须记住启用它.
归档时间: |
|
查看次数: |
29447 次 |
最近记录: |