实体框架:设置新对象引用时自动更新外键

时间:2010-06-11 15:16:58

标签: linq-to-sql entity-framework

我正在将现有的应用程序从Linq移植到SQL到Entity Framework 4(默认代码生成)。

我注意到两者之间的一个区别是重置对象引用时不会更新外键属性。现在我需要决定如何处理这个问题。

例如,假设您有两种实体类型,Company和Employee。一家公司有很多员工。

在Linq To SQL中,设置公司还会设置公司ID:

var company=new Company(ID=1);
var employee=new Employee();
Debug.Assert(employee.CompanyID==0);
employee.Company=company;
Debug.Assert(employee.CompanyID==1); //Works fine!

在实体框架中(并且不使用任何代码模板自定义),这不起作用:

var company=new Company(ID=1);
var employee=new Employee();
Debug.Assert(employee.CompanyID==0);
employee.Company=company;
Debug.Assert(employee.CompanyID==1); //Throws, since CompanyID was not updated!

如何使EF的行为与LinqToSQL相同?我看了默认代码生成T4模板,但我无法弄清楚如何进行必要的更改。看起来像一个单行应该可以做到这一点,但我无法弄清楚如何获得给定引用的ID属性。

2 个答案:

答案 0 :(得分:4)

根据我在默认T4模板中看到的,实体的外键属性不直接链接到与密钥关联的实体引用。

Theres夫妇可以解决从Linq到SQL迁移到EF4的问题。其中之一是注册您的关联的AssociationChanged事件,以便它自动更新您的字段。在您的上下文中,一种方法可能是这样的:

// Extends Employee entity
public partial class Employee
{
    private void CompanyChanged(Object sender, CollectionChangeEventArgs e)
    {
        // Apply reactive changes; aka set CompanyID
        // here
    }

    // Create a default constructor that registers your event handler
    public Employee()
    {
        this.CompanyReference.AssociationChanged += CompanyChanged;
    }
}

就个人而言,如果您想限制维护此类逻辑所需的维护,我建议您更改T4模板(自行更改或找到一个),以便在{CompanyId时设置Company 1}}如前所示进行了更改。

Gil Fink为使用EF4的T4模板写了一篇很好的介绍,你可以查看Scott Hanselman包含大量有用的链接和资源来使用T4模板。

最后一点,除非我弄错了,直接访问外键作为实体的属性是从EF3.5到4的新内容。在3.5中,只有通过相关实体才能访问它({{ 1}})。我相信这个功能是在EF4中添加的,这样你就不必加载关联(使用“include”),以便在从数据存储中选择时获取外键。

也许EF对此的看法是,如果你有了这个关联,那么首先要通过协会来获取ID。但这只是猜测,因为我没有引用它来支持它。

[编辑2010-06-16] : 在对edmx xml元素进行快速阅读和分析之后,我发现了一个名为ReferentialConstraint的内容,它似乎包含指定FK_Relation的外键字段。

下面是修改默认T4 edmx模板内部的代码片段,编写导航属性部分。 (Employee.Company.CompanyID),在未修改的模板的第388行附近。试着忽略可怕的格式......

Template_RegionNavigationProperties

我粗略测试了它,但它是一个给定的一些验证和这样的缺失。也许无论如何,它都可以为您提供解决方案。

答案 1 :(得分:2)

感谢您提供此解决方案。我已经增强了它(不再依赖于特定的命名约定),并且还包含在一个修复程序中,该修复程序还修复了Entity Framework模板的其他问题。

Check here for my solution and fixed code generation template