使用DBSet<>这会创建循环引用

时间:2013-10-23 13:09:41

标签: c# entity-framework reference

我似乎无法弄清楚如何使用EntityFramework

引用另一个dll中的类(在同一个解决方案中)

错误1找不到类型或命名空间名称“Animal”(您是否缺少using指令或程序集引用?)

如果我尝试添加引用,我会创建一个循环引用。

public class AnimalDBContext : DbContext
{
    public AnimalDBContext()
        : base()
    {

    }

    public DbSet<Animal> Animals { get; set; }

}

这个版本对我来说更合适。但它可能不是吗?

public class AnimalDBContext<TEntity> where TEntity  : DbContext
{
    public AnimalDBContext()
        : base()
    {

    }

    public DbSet<TEntity> Animals { get; set; }

}

这会导致以下编译器错误。

 AnimalDBContext < Animal > animal = new AnimalDBContext<Animal>();

Error   3   The type 'AnimalLibrary.Animals.Animal' cannot be used as type
parameter 'TEntity' in the generic type or method
ObjectSaver.AnimalDBContext<TEntity>'. There is no implicit reference conversion from
AnimalLibrary.Animals.Animal' to 'System.Data.Entity.DbContext'.    

1 个答案:

答案 0 :(得分:4)

因此,如果我理解正确,您的“存储库”程序集引用您的“域”程序集,这是有道理的,而您的“域”程序集引用您的“存储库”程序集,而不是。

您的实体类不应引用用于创建它们的存储库,原因如下:

  • 它创建了一个循环依赖,正如您已发现
  • 这使得模拟单元测试的类变得更加困难
  • 您的实体与某种类型的提供商绑定,使得将来很难更改提供商

将存储库中的依赖项从域移动到单独的程序集中。

根据你的评论,听起来你需要至少三个装配 -

  • A)数据访问,
  • B)业务逻辑,
  • C)域类。

理想情况下 A和B应该引用C而不是彼此(反之亦然)。您的域类不需要知道如何坚持自己 - 这是别人的责任。

可以从A引用B,但这会阻止您“嘲笑”您的存储库以测试您的业务逻辑。绑定数据访问和业务逻辑将位于主应用程序引用的“服务”层中。同样,您可以将服务和应用程序层捆绑在一起,但这也会增加耦合并降低可测试性。