保存时未关联父对象的关联实体

时间:2012-04-27 00:54:44

标签: entity-framework-4 dbcontext

我正在开发一个使用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,并且随着实体的增长和添加更多关联,需要越来越多的黑客攻击。有什么明显的东西我不见了吗?

** 更新 ** 根据Ladislav在下面的回答,我在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) #>)]
<#+
    }
}

希望有所帮助!

1 个答案:

答案 0 :(得分:1)

听起来您的BillingAddress映射不正确,因为AddressId不会被处理为关系的FK。

尝试将此属性添加到导航属性中:

[ForeignKey("AddressId")]
public Address BillingAddress { get;set; }

如果您首先将EDMX与数据库一起使用,请确保这些类之间存在正确配置的关系。 EF在其商店映射和商店映射中使用此信息定义操作的顺序。如果您没有正确配置的关系,则按类型名称的字母顺序处理实体=&gt;在Account之前处理Address

顺便说一下。您确定Account来电期间SaveChanges没有重复吗?