【问题标题】:Is it ok to make calls to data layer/repo from POCO?从 POCO 调用数据层/repo 可以吗?
【发布时间】:2011-08-31 03:43:44
【问题描述】:

我正试图弄清楚如何为我的购物车设置一个干净的架构,而不会过度架构它或以一个贫乏的领域模型告终。现在我只想使用没有任何 ORM 框架的标准 ADO 数据库逻辑。 (我也在学习 EF4.1,但还不够好,无法在生产中使用)

理想情况下,我只需要为每个业务对象/实体创建一个 POCO,以及一个用于处理持久性的存储库/数据类。为简单起见,我正在考虑将 POCO 紧密耦合到数据层,它将返回 POCO。如果我也将 DTO 添加到组合中,那么我最终会为每个区域(gc、订单、项目、付款等)拥有 5-6 个类文件,这对于一个简单的应用程序来说似乎太多了。我以后总是可以改进的。

我正在做的第一堂课是礼券。其中一种方法是创建一个新的 GC。在这种方法中,我需要查询数据库以确保系统中不存在新代码。在这个方法中只调用数据层/repo 可以吗?

数据层/存储库应该是静态的吗?我应该只通过 POCO 本身暴露它吗?

我是否应该完全放弃数据层,直接在我的 POCO 中调用数据(活动记录样式)?

我需要一个简单的架构,它可以让我在不使事情过于复杂的情况下分离一些关注点。至少在未来几年内,数据库提供程序和表结构不会改变。

这是一些代码.. 只需要弄清楚零件的去向即可。

public GiftCertificateModel
{
    public int GiftCerticiateId {get;set;}
    public string Code {get;set;}
    public decimal Amount {get;set;}
    public DateTime ExpirationDate {get;set;}

    public void Redeem(string code, decimal amount)
    {
        //need to validate the input
        //need to insert a record to the transaction log table (call the repo or does this entire method need to be in the repo?)
    }

    public void GetNewCode()
    {
        //need to create random alpha num code
        //need to make sure the code is unique in the db... (again, (call the repo or does this entire method need to be in the repo?
    }

}




public GiftCertificateRepo : DALBase (DALBase has methods for connecting, etc)
{

    //mapping code here to map SQLDataReader values to GiftCertificateModel properties
    //i can also setup separate DTOs if it makes more sense...

    //should the repo be static?
    public static GiftCertificateModel GetById(int GiftCertificateId)
    {
        //call db to get one and return single model

    }

    public static bool IsUnique(string code)
    {
        //call db to see if any records exists for code

    }

    public static List<GiftCertificateModel> GetMany()
    {
        //call db to get many and return list

    }

    public static void Save(GiftCertificateModel gc)
    {
        //call db to save

    }
}

调用代码:

GiftCertificateModel gc = new GiftCertificateModel();
gc.Code = gc.GetNewCode(); //do i call the is unique here or in the GetNewCode method?
gc.Amount = 10;
gc.ExpirationDate = "1/1/2012";
GiftCertificateRepo.Save(gc);

【问题讨论】:

  • 请不要给你的GC一个Collect()方法。
  • 您不能在数据库级别创建您的 NewCode 吗?在我的应用程序中,我通常在保存新记录之前在存储过程中创建一个新的 guid。

标签: c# asp.net architecture poco


【解决方案1】:

根据定义,POCO 对持久性无知,即它不知道这一点以及它是如何被持久化的。

如果您将业务对象耦合到存储库或持久层,根据您的具体情况,这可能完全没问题,但它不再是 POCO。

【讨论】:

  • 只要 POCO 不知道持久层,那么如果持久层本身可以接受/返回 POCO 会有什么不同?
  • 也许我误解了你的问题。我以为您想在 POCO 中包含持久性调用,这样就不再是 POCO。
  • 我应该如何处理我的 POCO 中需要获取数据来计算属性或检查存在的情况?这些是否应该是单独的服务类(例如 - 需要查看 GC 代码是否是唯一的,如果不是,它应该给出一个新代码)。在代码隐藏文件中包含这个逻辑似乎很愚蠢。
  • 我要么使用服务类进行编排,要么使用依赖注入将存储库移交给业务对象。
  • DI 在这一点上有点超出我的想象。顺便说一句,你建议转向 EF 还是...?
【解决方案2】:

有几种系统/意识形态,但他们都同意持久性不是业务类的一部分。制作一个单独的数据访问层来存储和检索您的 POCO。

【讨论】:

  • 根据我的阅读,你应该有一个丰富的域模型,所以我认为在 POCO 本身中有验证和其他业务逻辑是可以的(否则它只是一个 DTO / 贫血模型) .因此,当创建新的 GC 时,需要根据 db 检查代码以查看它是否是唯一的……我该如何处理?
  • @developr - 请参阅下面的评论
【解决方案3】:

通过将 POCO(数据表示)与存储库对象(数据如何存储/检索的表示)分开,您将能够在未来更轻松地从 ADO 切换到更高级的 ORM 系统 - 这些代码更改将被隔离到一个地方。

更好的是,定义一个 IRepository 接口并让您的 ADO 存储库类实现它。然后,您的应用应仅与 IRepository 一起使用,从而使将来测试或切换存储库实现变得更加容易。

【讨论】:

  • @Robert Levy - 我只是不明白如何将存储库模式应用到我的解决方案中。
  • @developr - 我会替换这个:“GiftCertificateModel gc = new GiftCertificateModel();gc.Code = gc.GetNewCode();”用“GiftCertificateModel gc = gcRepo.CreateNew();”然后 repo 负责创建 gc 对象并为其提供有效代码
  • @Robert Levy - 感谢您的建议。所以我只是将参数(exp date、amount 等)传递给 repo 方法?然后输入验证也会在回购中完成吗?如果是这样,那么 poco 会包含哪些类型的“丰富”功能?
  • @developr - 可以在模型中进行验证。我不会将这些参数传递给 CreateNew 方法,您可以在取回对象后设置这些属性。但让 CreateNew 做特定于存储库的工作(确保新 GC 的良好、唯一代码)
  • @Robert Levy - 澄清一下,可以在存储库之外创建一个 gc 对象吗?而且,据我了解,永远不应出于任何原因在 POCO 本身中调用 repo?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-08-16
  • 1970-01-01
  • 1970-01-01
  • 2014-08-25
  • 2014-11-22
相关资源
最近更新 更多