2012-03-12 98 views
2

我在实体框架中有两个实体。现在我想通过将DAL实体的接口放入域来分离它们。实体框架中的接口(接口中的接口)

所以,最终的结果将是:

DAL

  • 人:IPerson(EF实体)
  • 书:IBOOK(EF实体)

  • 接口(文件夹)
    • IPerson
    • 的iBook
  • 人(域实体)
  • 书(域实体)

现在的问题是,应该我Dal.Person有一个虚拟书或IBOOK ? 应该如何既DAL.Person,IPerson和Domain.Person样子(给我公正的接口非常小的例子)

+0

我不认为应该DAL实现Domain接口。 – Jodrell 2012-03-12 11:08:26

+0

@Jodrell http://dotnetslackers.com/articles/aspnet/Building-a-StackOverflow-inspired-Knowledge-Exchange-Three-Tiers-to-MVC-Hooray-Reversing-Dependencies.aspx说你应该删除依赖关系到EF/L2SQL – Julian 2012-03-12 11:33:49

+0

域是BLL还是模型? – Jodrell 2012-03-12 11:37:54

回答

1

EF不支持与接口的工作,所以你不能有public virtual IBook ...Person实体,如果你希望将其用作EF处理的导航属性。

+0

然后,删除实体框架和域类之间的依赖关系的正确方法是什么? – Julian 2012-03-12 11:42:10

+2

使用POCO类。 – 2012-03-12 11:45:22

1

您的问题的答案完全取决于您的目标。

如果您正在创建域级接口,并且您可能(在某个阶段之后)将DAL从实体框架交换到完全不同的(例如第三方Web服务或可能是xml序列化)的DAL上 - 那么您将致力于完全分离Domain和DAL之间的任何具体逻辑。

如果可能的话,你希望你的域对域的entites /接口和你的DAL操作上DAL实体/接口操作,同时实现在数据访问

因此指定的接口,你的DAL对象DAL。 Person应该包含一个Book对象,并在域级执行IPerson接口。

我会给所要求的一些例子:

#region Domain Objects 


    public interface IPerson 
    { 
     List<IBook> Books { get; private set; } 
    } 

    public interface IBook 
    { 
     string Name { get; private set; } 
    } 

    #endregion 

    #region DAL/Entity Framework Auto Generated classes 

    public class Person : IPerson 
    { 
     public List<Book> Books {get; private set;} 
    } 

    public class Book : IBook 
    { 
     public string Name { get; private set; } 
    } 

    #endregion 

相反Jodrells评论,我想,如果有一个要求,“热插拔”的数据访问层有可能是对的情况下, DataAccess层实现Domain层中描述的接口契约。老实说,我很少见到这个要求 - 通常你最好是扩展自动生成的实体框架类(通过partial)并传递应用程序,消除需要的重复通过指定域对象和契约本身。 所以实质上,你的实体框架类变为你的域层的

而且我要指出,你应该使用POCO类按上述评论

+0

在我的niavety,我认为这是这种情况 – Jodrell 2012-03-12 11:49:16

+0

@帕特里克麦克利感谢您的真正好评!虽然让实体框架类成为我的领域层是我的问题。该客户希望首先快速实施Entity Framework以便快速开发。但后来他想用纯SQL交换整个EF,所以它会更快。在旁注中,拉迪斯拉夫(其他评论)说,在EF中不可能使用接口。 – Julian 2012-03-12 11:49:58

1

我从来没见过使用的接口去耦EF。我知道它们被用于依赖注入的去耦,但也许EF在后台会进行太多的工作(动态代理,更改检测)。

我建议实施一个存储库层。

步骤1

从最简单的图案 - 在一个DAL层域和EF,模型(Person和书)使用代码的标准EF过程首先。 EF在DbSet<Person>DbSet<Book>中实现了存储库功能(但当然这种类型的存储库已锁定到EF中)。

使可交付的应用程序适用于这种模式,您可以很快演示功能。这使您可以专注于应用逻辑,而不用担心持久性问题。

步骤2

将域和DAL之间的存储库的类。将域调用替换为DbSet<Person>DbSet<Book>,并调用存储库中的IQueryable<Person>IQueryable<Book>。资源库集合最初只指向EF DbSet<>集合。

在存储库中实现Save()。最初,它只是调用DbContext.SaveChanges()。

检查功能是否保持不变。

步骤3

更换库的IQueryable<>的与无论是在新的DAL相当于源。这可能会也可能不会很棘手,具体取决于新DAL的形状。

我遵循这种流程 - 从一个XML序列化的DAL开始,将它移至EF,将一个表重构为本地XML文件,然后下一步将重构另一个表到ESB上的Web服务。

BTW,您提到用性能替换EF与SQL。我们发现EF缓慢批量插入,因为它使用了逐行的样式。

要解决这个问题,我基于EF仓库(而不是大规模更换EF的具有其他功能,我们真的很喜欢)内实现使用SqlBulkCopy。这很快,但需要一段时间拼凑在一起。

0

我一直对AGES有这个问题。

在过去,我用AutoMapper使用过DTO,但这看起来并不是很优雅,但我认为我找到了一个稍微整洁的方式 - 看看它是否适合您的设计。

基本上你公开两个链接在你 - 在你的具体类 - 一个implemetents iBook的书和一个实现图书BookNavigation

第一个实现了接口的要求(IBOOK),第二个实现的具体类让EF快乐。然后,您将这两个绑定到相同的私人书籍的相同。

我在这里更详细解释一下:

http://bretthargreaves.wordpress.com/2014/11/11/entity-framework-and-interface-issues/