Entity framework 4 保存时未附着到父对象的关联实体
我正在开发一个使用EF4.2和database first development的应用程序,使用标准T4模板生成DbContext和POCO。T4模板生成如下实体:Entity framework 4 保存时未附着到父对象的关联实体,entity-framework-4,dbcontext,Entity Framework 4,Dbcontext,我正在开发一个使用EF4.2和database first development的应用程序,使用标准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 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();
}
当我为现有帐户创建帐单地址时,我的代码如下:
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()之后添加以下代码:
这可能会起作用,但需要对数据库进行第二次SQL更新,并且随着实体的增长和添加更多关联,需要越来越多的黑客攻击。有什么明显的东西我遗漏了吗
**更新**
根据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) #>)]
<#+
}
}
void WriteKeyAttribute(CodeGenerationTools代码、NavigationProperty NavigationProperty、MetadataTools ef)
{
var dependentProperties=navigationProperty.GetDependentProperties();
if(dependentProperties.Any())
{
var keys=新列表();
foreach(dependentProperties中的var键)
{
Add(String.Format(“{0}\”,key.Name));
}
#>
[ForeignKey()]
听起来您的BillingAddress映射不正确,因为AddressId未作为关系的FK处理
尝试将此属性添加到导航属性:
[ForeignKey("AddressId")]
public Address BillingAddress { get;set; }
若要将EDMX与数据库一起使用,请首先确保这些类之间存在正确配置的关系。EF在其存储映射中使用此信息,存储映射定义操作序列。若未正确配置关系实体,则按其类型名称的字母顺序处理帐户
在地址之前处理
顺便说一句。你确定你的
账户在你的保存更改通话中没有重复吗?非常感谢你的建议,@Ladislav!我更新了我的T4模板以设置ForeignKey属性,这似乎解决了问题-地址的插入发生在账户更新之前,新的一代“外键”列中添加了已删除的主键。对于感兴趣的任何人,我将使用T4代码更新原始问题。