完全贫血 - 我在哪里可以将这些数据移出我的模型?

时间:2014-11-10 16:31:52

标签: c# anemic-domain-model

我得到了几十个遗留的SQL语句,每行数百行。在共享的Models项目中,每个SQL都映射到具有自己唯一POCO的代码。

例如,SQL Select Name, Birthday From PeopleModels项目中具有等效POCO:

public class BirthdayPerson : SqlResultBase {
    public string Name { get; set; }
    public datetime Birthday { get; set; }

    //SqlResultBase abstraction:
    public string HardcodedSql { get {
        return "Select Name, Birthday From People";
    }}
}

在我的DAL中,我有一个单个通用SQL运行器,其<T>代表SQL的POCO。所以我的业务逻辑可以调用GetSqlResult<BirthdayPerson>()

public IEnumerable<T> GetSqlResult<T>() where T : SqlResultBase, new() {
    return context.Database.SqlQuery<T>((new T()).HardcodedSql);
}

问题是我的Models库在整个应用程序中使用,我不希望在该HardcodedSql属性中跨应用程序公开SQL。

这是我正在使用的架构:

Suamere's Domain

3 个答案:

答案 0 :(得分:1)

最简单的解决方案是制作HardcodedSql internal而不是public,因此它只能在DAL项目中显示。如果DAL是与模型分开的项目,则可以使用InternalsVisibleTo将其公开给该项目。这假设您可以相应地配置项目结构。

答案 1 :(得分:1)

我建议可能有两种方法来处理这个问题。

至于第一种方法,我宁愿改变访问sql的方式,并在方法中本地包装调用。因此,类可能有一个名为public IEnumerable GetFromSql()的函数,您可以在上下文中传递,或者创建一个新函数,我不确定您是如何在项目中设置EF的。这样你就不会公开地暴露原始的sql,因为你宁愿把它变成私有变量或局部常量,也许只是从函数中访问它。

作为第二个选项,我实际上已经完成了这个并且结果非常好,我将所有sql移动到视图并使用EF来访问它们。这样我的代码就没有sql污染了。 看到模型已经存在,调用视图的结果将与您已有的类型相匹配。

答案 2 :(得分:1)

首先,您必须将模型(即POCO)与实际属于DAL的SQL分开。控制反转是正确的方法。而不是通用的sql runner,最好在IoC容器中注册从抽象存储库(例如IRepository<MyPOCO>)到包含SQL的实现的映射。

编辑:更具体一点,一个可能的解决方案:

  • 将所有SQL放置在DAL内的单独文件中,例如放置到一组具有名称约定的嵌入式资源文件,例如, Legacy- {0} .sql其中{0}是POCO的名称。
  • 创建使用POCO名称作为密钥的旧存储库的通用实现,并从资源集中选择相应的Legacy- {0} .sql文件。请注意,可能还有其他实现使用其他数据访问技术,如ORM。
  • 在组合根目录中明确所有从旧版POCO到遗留实现的映射:IRepository<MyPOCO1> => LegacyRepo<MyPOCO1>; IRepository<MyPOCO2> => LegacyRepo<MyPOCO2>; etc。此外,您可以将其他映射从非遗留实体注册到其他存储库实现。
相关问题