我必须承认,EF 4.1 RC Codefirst,DataAnnotations和FluentAPI的功能对我来说仍然是压倒性的。有时我真的不知道我在做什么;-)请看下面的POCO:
public class Country
{
[Key]
public Guid ID { get; set; }
[Required]
public virtual Currency Currency { get; set; }
}
public class Currency
{
[Key]
public Guid ID { get; set; }
public virtual ICollection<Country> Countries { get; set; }
}
总体思路:每个国家都需要有货币。但是根本不需要将货币分配给一个国家。
如果让EF创建相应的数据库,则按照约定将关系设置为CASCADE DELETE。换句话说:如果删除货币,也会删除相应的国家/地区。但在我的情况下,这是不我想要的。
我在FluentAPI中提出了一些代码,以便禁用CASCADE DELETE:
modelBuilder.Entity<Country>()
.HasRequired(cou => cou.Currency)
.WithOptional()
.WillCascadeOnDelete(false);
我认为这意味着:每个国家都需要一种货币。此货币可能有零个,一个或多个国家/地区(可选)。每当我删除一种货币时,相应的国家(如果有的话)都不会被级联删除。
令人惊讶的是,如果删除相应的货币,给定的方法仍会级联删除国家/地区。谁能告诉我我想念的是什么?
答案 0 :(得分:5)
首先,您已将货币指定为国家/地区的必填字段,因此您无法删除货币。您需要删除[必需]。
其次,您的模型构建器需要以下内容:
modelBuilder.Entity<Country>()
.HasRequired(cou => cou.Currency) //note optional, not required
.WithMany(c=>c.Countries) //define the relationship
.WillCascadeOnDelete(false);
第三,您需要明确删除对您要删除的实体的引用:
Currency c = context.Currencies.FirstOrDefault();
c.Countries.Clear(); //these removes the link between child and parent
context.Currencies.Remove(c);
context.SaveChanges();
[编辑] 因为我怀疑在翻译中丢失了一些内容,所以找到完整的代码来演示无级别删除是如何工作的。
public class Country{
[Key]
public Guid ID { get; set; }
public virtual Currency Currency { get; set; }
}
public class Currency{
[Key]
public Guid ID { get; set; }
public virtual ICollection<Country> Countries { get; set; }
}
public class MyContext : DbContext{
public DbSet<Currency> Currencies { get; set; }
public DbSet<Country> Countries { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder){
modelBuilder.Entity<Country>()
.HasRequired(country => country.Currency)
.WithMany(currency => currency.Countries)
.WillCascadeOnDelete(false);
}
}
class Program{
static void Main(string[] args){
Database.DefaultConnectionFactory = new SqlCeConnectionFactory("System.Data.SqlServerCe.4.0");
Database.SetInitializer(new DropCreateDatabaseAlways<MyContext>());
using (MyContext context1 = new MyContext()){
Currency c = new Currency{ID = Guid.NewGuid()};
context1.Currencies.Add(c);
c.Countries = new List<Country>();
c.Countries.Add(new Country{ID = Guid.NewGuid()});
context1.SaveChanges();
}
using (MyContext context2 = new MyContext()){
Currency c = context2.Currencies.FirstOrDefault();
context2.Currencies.Remove(c);
//throws exception due to foreign key constraint
//The primary key value cannot be deleted
//because references to this key still exist.
//[ Foreign key constraint name = Country_Currency ]
context2.SaveChanges();
}
}
}
保存时会出错,因为您删除的是必需的外键。