Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/entity-framework/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
.net 设计问题POCO对象/DAL访问_.net_Entity Framework_Repository Pattern_Poco - Fatal编程技术网

.net 设计问题POCO对象/DAL访问

.net 设计问题POCO对象/DAL访问,.net,entity-framework,repository-pattern,poco,.net,Entity Framework,Repository Pattern,Poco,我想实现典型的三层体系结构。我目前的做法如下 DAL-使用EF 4.0和我的每个实体的存储库。通过接口访问 我在考虑使用POCO对象。我的第一个问题是我应该把它们放在哪里 文件夹?在被所有其他项目引用的部件中 BLL—如何将数据从DAL获取到BLL,然后最终获取到GUI 如果我在BLL中有一大堆管理器类,比如CustomerManager,这是一个好方法吗。这些类将访问BLL中相应的存储库,然后将对象传递给GUI 或者您认为最好将存储库放在BLL中,并直接从我的say buttonevent

我想实现典型的三层体系结构。我目前的做法如下

  • DAL-使用EF 4.0和我的每个实体的存储库。通过接口访问
  • 我在考虑使用POCO对象。我的第一个问题是我应该把它们放在哪里 文件夹?在被所有其他项目引用的部件中
  • BLL—如何将数据从DAL获取到BLL,然后最终获取到GUI 如果我在BLL中有一大堆管理器类,比如CustomerManager,这是一个好方法吗。这些类将访问BLL中相应的存储库,然后将对象传递给GUI
或者您认为最好将存储库放在BLL中,并直接从我的say buttoneventhandler访问它们


希望你能给黑暗带来一些光明

我们在DAL有回购协议。BLL通过接口引用存储库-因此存储库与DAL绑定,但与BLL分离。我不知道为什么存储库不能直接在BLL中。我们把它们放在DAL里,因为我们没有任何逻辑。然后,我们在BLL中有“管理器”,它们包装存储库并处理特定于实体的逻辑

FWIW我们实际上有一个通用的
存储库(面向对象)
,并根据需要使用unity来实例化适当的存储库-它非常紧凑而且非常优雅。我们所有的POCO实体都实现了IEntity,其中包含我们所有实体共有的
Id
CreatedDate
等。当您需要一般性地处理任何类型的实体时,这提供了一些其他好处-
CreatedDate
由存储库在调用
CreateInstance()
时设置,
ModifiedDate
由上下文本身在提交状态为
Modified
的实体时设置

我们将实体保存在一个单独的项目中——DAL需要能够引用它们,BLL也是如此。您不希望它们出现在DAL中,因为调出DAL会导致问题。你不能把它们放在BLL中,否则你会得到一个循环引用。实体的配置可以存在于DAL中,因为它是特定于数据源的

我们试图坚持BLL接受原语和返回实体。在UI中保留实体的时间过长时要小心,尤其是在web应用程序中,因为当您将实体返回到BLL进行处理时,DAL下的上下文可能不同(即跨存储在会话或类似会话中的请求)这可能会导致从上下文中附加/分离实体的各种乐趣,并失去一些好处,如更改跟踪


希望这会有所帮助,但如果您需要任何澄清,请让我知道,您可以通过将存储库和POCO保留在同一个项目中来保持这一点非常简单。这基本上就是您的数据域模型。您的POCO是公共的,存储库接口也是公共的。您应该将您的具体存储库保留在此项目内部

您的BLL可以是一个经典的外观或服务定位器。在将数据移交给UI之前,此项目将对您的数据进行处理并应用任何相关的业务规则。这还将负责在将数据发送到DAL之前验证来自UI的数据。

这是我们的设置:

Company.Project.Domain.Model      (POCOs)
Company.Project.Business.Services (BLL)
Company.Project.Data.Repositories (Repository)
Company.Project.Web               (Presentation)
  • POCO在他们自己的装配中。不引用任何内容,但被所有人引用
  • BLL对存储库执行查询,应用业务规则和规则返回
    i收集
    T
    。参考存储库(通过
    IRepository
    通用接口)和POCO
  • Repository是一组实现
    IRepository
    的泛型类,用于提供对底层存储的基本持久性。查找、添加、删除等。返回
    IQueryable
    。参考POCO,由BLL参考
  • 演示文稿是UI。参考POCOs和BLL
最终的结果是一种类似堆栈的方法,因为基本上所有东西都是通过接口(和DI注册表)实现的,所以灵活性是巨大的

我们有通过DI注入测试项目的模拟存储库,以及通过DI注入BLL的实体框架存储库

来自UI->DB的示例流:

// "Company.Project.Web.ProductsController.cs"
public class ProductsController : BaseController
{
   private IProductService _productService;

   public ProductsController(IProductService productService)
   {
      this._productService = productService; // DI makes me happy :)
   }

   public ActionResult GetOrdersForProduct(Product product)
   {
      var orders = _productService.GetOrders(product);
      return View(orders);
   }
}

// "Company.Project.Business.Services.ProductService.cs"
public class ProductService : IProductService
{
   private IRepository<Product> _productRepository;

   public ProductService (IRepository<Product> productRepository)
   {
      this._productRepository = productRepository; // DI makes me happy :)
   }

   public ICollection<Orders> GetOrdersForProduct(Product product)
   {
      return _productRepository
                .Find()
                .ForProduct(product) // IQueryable<Product> pipe/extension filter
                .ToList();
   }
}

// "Company.Project.Data.Repositories.GenericRepository.cs
public class GenericRepository<T> : IRepository<T> where T : class
{
   private IObjectSet<T> _objectSet;

   public GenericRepository(IUnitOfWork unitOfWork)
   {
      CurrentContext = unitOfWork as SqlServerUnitOfWork;
   }

   public IQueryable<T> Find()
   {
      return CurrentContext.GetEntitySet<T>();
   }

   protected SqlServerUnitOfWork CurrentContext { get; private set; }

   protected IObjectSet<T> CurrentEntitySet
   {
      // some plularization smarts in "SqlServerUnitofWork.cs", to dynamically pull
      // back entity set based on T.
      get { return _objectSet ?? (_objectSet = CurrentContext.GetEntitySet<T>()); }
   }
}
/“Company.Project.Web.ProductsController.cs”
公共类ProductsController:BaseController
{
私有IPProductService\u productService;
公共产品控制器(IPProductService产品服务)
{
这个。_productService=productService;//DI让我很高兴:)
}
公共操作结果GetOrdersForProduct(产品)
{
var orders=\u productService.GetOrders(产品);
返回视图(订单);
}
}
//“公司.项目.业务.服务.产品服务.cs”
公共类ProductService:IPProductService
{
私人IRepository\u productRepository;
公共产品服务(IRepository productRepository)
{
这个。_productRepository=productRepository;//DI让我很高兴:)
}
公共ICollection GetOrdersForProduct(产品)
{
return\u productRepository
.Find()
.ForProduct(product)//液体管道/延伸过滤器
.ToList();
}
}
//“Company.Project.Data.Repositories.GenericRepository.cs
公共类GenericRepository:IRepository,其中T:class
{
私有IObjectSet\u对象集;
公共总报告(IUnitOfWork unitOfWork)
{
CurrentContext=unitOfWork作为SqlServerUnitOfWork;
}
公共IQueryable Find()
{
返回CurrentContext.GetEntitySet();
}
受保护的SqlServerUnitOfWork CurrentContext{get;private set;}
受保护的IObjectSet CurrentEntitySet
{
//“SqlServerUnitofWork.cs”中的一些多极化智能,用于动态拉取
//基于T。
获取{return\u objectSet??(\u objectSet=CurrentContext.GetEntitySet());}
}
}
<