仍然无法首先使用实体框架代码配置与ON DELETE SET NULL规则的关系.作为一种解决方法,您必须在内存中加载所有相关实体,然后在删除父实体时,EF将发出SQL命令以将其外键设置为Null.
这一点,虽然使用类似的东西自己实现这一点是微不足道的:
protected override void Seed(Context context)
{
context.Database.ExecuteSqlCommand("ALTER TABLE dbo.Guests DROP CONSTRAINT Guest_PreferredLanguage");
context.Database.ExecuteSqlCommand("ALTER TABLE dbo.Guests ADD CONSTRAINT Guest_PreferredLanguage FOREIGN KEY (LanguageID) REFERENCES dbo.Languages(LanguageID) ON UPDATE NO ACTION ON DELETE SET NULL");
}
Run Code Online (Sandbox Code Playgroud)
(例子来自这篇文章.)
我可以看到这种方法没有问题:加载的子实体将与数据库保持同步,因为EF将更新(设置为null)其外键和引用属性,并且数据库中的其他记录受到影响不会有任何危害,因为它们具有反正没装好.
那么,为什么这个功能仍然缺失呢?有一些隐藏的障碍吗?
EntityFramework的文档声明可能存在以下行为:
如果依赖实体上的外键可以为空,则Code First不会在关系上设置级联删除,并且当删除主体时,外键将设置为null.
(来自http://msdn.microsoft.com/en-us/jj591620)
但是,我无法实现这样的行为.
我使用代码优先定义了以下实体:
public class TestMaster
{
public int Id { get; set; }
public string Name { get; set; }
public virtual ICollection<TestChild> Children { get; set; }
}
public class TestChild
{
public int Id { get; set; }
public string Name { get; set; }
public virtual TestMaster Master { get; set; }
public int? MasterId { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
以下是Fluent API映射配置:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<TestMaster>()
.HasMany(e => …Run Code Online (Sandbox Code Playgroud) 我是EF的新手,并且为了方便删除我的对象而苦苦挣扎.我的两个对象和相关的DbContext如下所示:
public class Context: DbContext
{
public Context() : base(){}
public DbSet<Person> Persons {get;set;}
public DbSet<Vehicle> Vehicles {get;set;}
}
public class Person
{
public int PersonID {get;set;}
public string Name {get;set;}
}
public class Vehicle
{
public int VehicleID {get;set;}
public int? PersonID {get;set;}
[ForeignKey("PersonID")]
public virtual Person Person {get;set;}
}
Run Code Online (Sandbox Code Playgroud)
如上所述,一个人可以链接到多个车辆.从人到车辆没有明确的链接,但是通过外键关系存在从车辆到"父母"人的链接.
然后我在我的代码中创建各种车辆,并将这些车辆链接到可选的人物对象(外键可以为空).
我的问题是删除Person对象.我通常会删除对象,如下所示:
private void DeletePerson()
{
using (var context = new Context())
{
int personID = 4; //Determined through other code
var person = context.Persons.Find(personID);
context.Persons.Remove(person); …Run Code Online (Sandbox Code Playgroud) c# ×1