我正在开发一个使用 EF 4.2 和数据库优先开发的应用程序,使用标准 T4 模板生成 DbContext 和 POCO。T4 模板生成如下实体:
public class Address
{
public int AddressId { get;set; }
public string Address1 { get;set; }
public string City { get;set; }
}
public class Account
{
public int AccountId { get;set; }
public string Name { get;set; }
public int AddressId { get;set; }
public Address BillingAddress { get;set; }
}
当我为现有帐户创建帐单地址时,我的代码如下所示:
public void Save(Account updated)
{
var existing = DbContext.Find(updated.AccountId);
MyContext.Entry(existing).CurrentValues.SetEntry(updated);
existing.Address = updated.Address;
MyContext.SaveChanges();
}
观察 SQL Server Profiler,我可以看到地址条目被插入到数据库中,但不幸的是,它发生在帐户条目更新之后,因此地址与其父帐户分离,当我下次加载帐户时,计费地址又是空的。
一种解决方法是在调用 SaveChanges() 之后添加以下代码:
if (existing.AddressId == null && existing.Address != null)
{
existing.AddressId = existing.Address.AddressId;
MyContext.SaveChanges();
}
虽然它可能有效,但需要对数据库进行第二次 SQL UPDATE,并且随着实体的增长和添加更多关联,需要越来越多的 hack。我有什么明显的遗漏吗?
**更新** 在下面 Ladislav 的回答之后,我在我的 T4 模板的 WriteNavigationProperty 中添加了对以下方法的调用:
void WriteKeyAttribute(CodeGenerationTools code, NavigationProperty navigationProperty, MetadataTools ef)
{
var dependentProperties = navigationProperty.GetDependentProperties();
if (dependentProperties.Any())
{
var keys = new List<string>();
foreach (var key in dependentProperties)
{
keys.Add(String.Format("\"{0}\"", key.Name));
}
#>
[ForeignKey(<#= String.Join(", ", keys) #>)]
<#+
}
}
希望有帮助!