Entity framework 4 保存时未附着到父对象的关联实体

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 {

我正在开发一个使用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 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代码更新原始问题。