在EF4.0中引入了FK relationships的概念,所以现在可以建立这样的一种模型:
public class Division
{
public int DivisionID {get;set} // Primary Key
public string Name {get;set;}
public virtual List<Lawyer> Lawyers {get;set;}
public virtual List<Unit> Units {get;set;}
}
public class Lawyer
{
public int LawyerID {get;set;} // Primary Key
public int DivisionID {get;set;} // Primary Key + FK to Division
public string Name {get;set;}
public virtual Division Division {get;set;}
public virtual List<Unit> Units {get;set;}
}
public class ProductTeam
{
public int ProductID {get;set;} // Primary Key
public int? DivisionID {get;set;} // FK to Division & Lawyer
public int? LawyerID {get;set;} // FK to Lawyer
public string Name {get;set;}
public virtual Division Division {get;set;}
public virtual Lawyer Lawyer {get;set;}
}
注意,这里Lawyer拥有组合主键LawyerID 和DivisionID。
Notice that the Lawyer has a Compound key made up of both the LawyerID and DivisionID.
当你在创建包含组合式外键Lawyer和Division的类ProductTeam的时候,事情讲变得有趣,如果你象下面这样操作:
var team = (from t in ctx.ProductTeams
where t.Lawyer.Name == “Fred Bloggs”
select t).FirstOrDefault();
team.Lawyer = null;
ctx.SaveChanges();
这里EF的真实操作是怎样的呢?
为了清除这个Relationship,这里到底是同时清除外键team.LawyerID和team.DivisionID呢还是仅仅清除外键team.LawyerID?
Does this mean clear team.LawyerID & team.DivisionID or just team.LawyerID?
从Relationship的角度来看,只要清除任何一个可空的外键就可以使这个Relationship被清除。
这里很难说用户倾向哪一种,与其介绍一些特殊的规定,我们还是来看看EF所使用的限制和规则,我们可以遵守:
当用户需要把一个Relationship设置成空的时候,EF将把所有可空的外键设置为空,无论该外键属性是否参与了其他Relationship。
根据上面的规则,这里EF是同时把DivisionID 和LawyerID两个外键属性都置空了,因为它们都返回到了Lawyer的导航属性中。
上面的方式将同时把Lawyer和Division两个对象同时置空,你真的想那样吗,或许不是。
如果你只是想置空Lawyer,你有两种选择:
选择一:改变模型中外键DivisionID的可空属性,在这里EF仅可以使LawyerID可空,这样Relationshiip将可以完整保留。但这种解决方案需要改变模型,这个并不是总是可以的,如果Division确实需要可空呢?
更好的办法是直接操纵未见属性:
var team = (from t in ctx.ProductTeams
where t.Lawyer.Name == “Fred Bloggs”
select t).FirstOrDefault();
team.LawyerID = null;
ctx.SaveChanges();
这样的方式仅仅涉及到了Lawyer,不会对Division造成影响。