【问题标题】:How to build EF query expression for persistence model using specification for domain model如何使用域模型规范为持久性模型构建 EF 查询表达式
【发布时间】:2013-12-22 14:17:00
【问题描述】:

我在域层中有域模型Task,在基础架构中有持久性模型eTask

class Task : IAggregateRoot, EntityBase
{
    private string taskText;

    public Task(string taskText)
        :this(null, taskText)
    {          
    }

    public Task(object id, string taskText)
        :base(id)
    {
        //argument validation
        this.taskText = taskText;
    }

    //some business logic here
}

...

class eTask
{
    public Guid ID { get; set; }
    public string TaskText { get; set; }
}

我有存储库接口 ITaskRepository 及其实现,它使用 EF 和持久性模型 eTask 并在返回结果项时将 eTask 映射到 Task

interface ITaskRepository : IRepository<Task>
{
    IEnumerable<Task> GetTasksBySpecification(ISpecification<Task> spec);
}

ISpecification 接口是这样的:

interface ISpecification<T>
{
    Expression<Func<T, bool>> IsSatisfiedBy();
}

问题出在ITaskRepository.GetTasksBySpecification 实现中。我试图找出如何将规范对象spec 转换为实体框架的实体eTask 的表达式。我该怎么做?

【问题讨论】:

  • 我会将eTask 重命名为Task 并开始将其用作域模型。实体框架允许你先编写领域模型。
  • EF 模型必须有公共的 getter 和 setter,但这对于有一些封装的域来说并不好,这就是我将域模型和持久性模型分开的原因
  • @IlyaPalkin 这不是关于 EF 可以做什么,而是关于在 DAL 中保留诸如 ORM 之类的持久性细节,而不是将它们暴露给应用程序,以避免将应用程序耦合到 ORM。并且应用程序对象不应该关心 ORM 的工作方式或知道您是否正在使用它。这就是存储库的重点。

标签: c# domain-driven-design specifications repository


【解决方案1】:

如果你想使用表达式,那么你必须编写自己的表达式解析器,它会生成相关的 linq2sql 表达式。

更简单的方法是使用简单的对象,专门用于特定条件

public class TaskSelectionCriteria
{
      public Guid? Id {get;set;}
      public string TaskText {get;set;}
}

然后在repo中可以检查Id是否不为null,添加Where(d=>d.Id=criteria.Id.Value),如果有TaskTExt,添加对应的EF条件等等。

它不像使用表达式那么酷,但它更容易实现和维护。并且您让应用程序的其余部分不知道 EF 的内容。

【讨论】:

    猜你喜欢
    • 2012-12-11
    • 2021-02-14
    • 2015-02-19
    • 2017-07-06
    • 1970-01-01
    • 2015-01-31
    • 1970-01-01
    • 1970-01-01
    • 2017-03-27
    相关资源
    最近更新 更多