存储库基础还是具体方法?

发布于 2024-11-24 20:37:29 字数 1106 浏览 6 评论 0原文

我一直在开发一个应用程序,并尝试应用 DDD 和其他工具(Nhibernate 和 asp.net MVC)。

在此应用程序中,我们需要在存储库的 Person 实体中按名称实现“搜索”。因此,我们有一个存储库基础(RepositoryBase 类),在此实现中,我有一个适用于该项目的通用方法。

public IEnumerable<T> FindAll(Expression<Func<T, bool>> condition) {
  return Session.QueryOver<T>().Where(condition);
}

在我的 asp.net mvc 应用程序中,我们可以像这样使用它:

var list = _repositoryPerson.FindAll(x => x.Name == "Felipe");

另一方面,我们可以为此任务创建一个特定的方法(在 RepositroyPerson 类中),例如:

public IEnumerable<Person> FindByName(string name) {
  return Session.QueryOver<Person>().Where(x => x.Name == name);
}

在我的 asp.net mvc 应用程序中,我们可以像这样使用它:

var list = _repositoryPerson.FindByName("Felipe");

我的问题是:

1 - 根据 DDD 满足此要求的推荐方法是什么?特定类还是基类?

2 - 有人推荐了一些使用 Nhibernate QueryOver 实现存储库基础(通用)的好方法?

如果有人可以帮助我,我将非常感激! 谢谢


更新:

例如,如果我需要复杂的搜索,例如组合条件...例如:姓名(可选)和年龄(可选)和城市(可选)和其他字段...每个字段都是可选的并组合与其他领域!是否推荐使用表达式?您将如何实现这段代码?

PS:对不起我的英语!

谢谢

I've been developing an application and I'm trying to aply DDD and other tools (Nhibernate and asp.net MVC).

In this app we have a requirement to implement a 'search' by Name in the repository's Person entity. So, we have a repository base (RepositoryBase class) and in this implementation I have a generic method that works for this item.

public IEnumerable<T> FindAll(Expression<Func<T, bool>> condition) {
  return Session.QueryOver<T>().Where(condition);
}

And in my asp.net mvc application, we could use it like:

var list = _repositoryPerson.FindAll(x => x.Name == "Felipe");

On the other hand, we could create a specific method (in RepositroyPerson class) for this task, like:

public IEnumerable<Person> FindByName(string name) {
  return Session.QueryOver<Person>().Where(x => x.Name == name);
}

in my asp.net mvc app, we could use it like:

var list = _repositoryPerson.FindByName("Felipe");

My questions are:

1 - What is the recommended way to meet this requirement in accordance with DDD? Specific or Base class ?

2 - Someone recommended some nice implementation of Repository base (generic) with Nhibernate QueryOver?

if someone could help me, I would really appreciate it!
Thanks


UPDATES:

If I need, for example, a complex search like combine the conditions... e.g.: name (optional) and age (optional) and city (optional) and other fields.... every field would be optional and combine with other fields! Using expression would be the recommended or no ? How would you implement this code?

PS: Sorry for my english!

Thanks

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

千年*琉璃梦 2024-12-01 20:37:29

为了两全其美,您可以像在基类中一样实现 FindByName 方法,将其标记为 protectedprotectedinternal< /code> (取决于您是否希望允许其他程序集定义存储库实现),然后从特定存储库对象中调用它。

protected internal IEnumerable<T> FindAll(Expression<Func<T, bool>> condition) {
  return Session.QueryOver<T>().Where(condition);
}

public IEnumerable<Person> FindByName(string name) {
  return base.FindAll(x => x.Name == name);
}

这将允许您为将使用该方法的情况编写特定的测试,同时还允许您更改 ORM 实现,而无需在很多地方进行更改。

更新:
为了在 FindAll 中组合多个条件,您可以简单地使用 Aggregate 组合它们(我没有使用 NHibernate 对此进行测试,但如果它损坏,您可以用 foreach 替换它)。

public IEnumerable<T> FindAll(IEnumerable<Expression<Func<T, bool>>> conditions)
{
    return conditions.Aggregate(Session.QueryOver<T>(), (current, condition) => current.Where(condition)).List();
}

然后方法可以采用可选参数,并创建传递给 FindAll 的条件列表。

   public IEnumerable<T> FindByParams(string name=null, string city=null)
   {
       var wheres = new List<Expression<Func<T, bool>>>();

       if (name != null)
       {
           wheres.Add(x => x.Name == name);
       }
       if (city != null)
       {
           wheres.Add(x => x.City == city);
       }
       return base.FindAll(wheres);
   }

In order to have the best of both worlds, you can implement the FindByName method generically as you have in the base class, mark it as protected or protected internal (depending on whether you want to allow other assemblies to define Repository implementations), then call it from your specific repository objects.

protected internal IEnumerable<T> FindAll(Expression<Func<T, bool>> condition) {
  return Session.QueryOver<T>().Where(condition);
}

public IEnumerable<Person> FindByName(string name) {
  return base.FindAll(x => x.Name == name);
}

This will allow you to write specific tests for the cases you will be using the method, while also allowing you to change out your ORM implementation without needing to change it in a ton of places.

UPDATE:
In order to combine multiple conditions in FindAll, you can simply combine them using Aggregate (I haven't tested this with NHibernate, but if it breaks, you can replace it with a foreach).

public IEnumerable<T> FindAll(IEnumerable<Expression<Func<T, bool>>> conditions)
{
    return conditions.Aggregate(Session.QueryOver<T>(), (current, condition) => current.Where(condition)).List();
}

Then methods could take optional parameters, and create a list of conditions that are passed to FindAll.

   public IEnumerable<T> FindByParams(string name=null, string city=null)
   {
       var wheres = new List<Expression<Func<T, bool>>>();

       if (name != null)
       {
           wheres.Add(x => x.Name == name);
       }
       if (city != null)
       {
           wheres.Add(x => x.City == city);
       }
       return base.FindAll(wheres);
   }
裂开嘴轻声笑有多痛 2024-12-01 20:37:29

这两种方法都有效,我将使用通用方法,但 findmyname 可以为您提供更好、更干净的代码。
我认为这取决于品味以及您希望 DDD 的纯粹程度。我将为更复杂的需求(例如搜索或其他东西)创建特定的方法,但保持简单是我的方法

both methods works i will use the generic method but the findmyname gives you better and clean code.
i think its a matters of tastes and how purist in DDD you want to be. i will create specific methods for more complex requirements like a search or something but keeping it simple is the way to go for me

无尽的现实 2024-12-01 20:37:29

我同意 Oscar 的观点 - 我更喜欢特定的方法,主要原因是它们更易于测试。围绕 IQueryable 和 Expression 对象构建合理的测试非常具有挑战性。

I agree with Oscar - I prefer specific methods for the main reason that they are much more testable. It is very challenging to build reasonable tests around IQueryable and Expression objects.

假情假意假温柔 2024-12-01 20:37:29

其他注意事项:

谁是存储库代码的使用者?如果您将存储库暴露给 gui 或其他可能难以或滥用更抽象的接口的开发人员,那么就有额外的动力来提供更清晰的特定接口。

界面有多臃肿?仅仅因为一个表达式可以几乎可以是任何东西,并不意味着它通常都是这样。但在这种情况下,也许是因为您可以在更新中组合搜索条件,然后会倾向于使用更抽象的方法,至少作为帮助者。

我个人倾向于尽可能使用更具体的界面

干杯,
贝里尔

Additional considerations:

Who are the consumers of your repository code? If you expose your repository to gui or other devs who may struggle or misuse a more abstract interface, then there is additional incentive to provide a clearer specific interface.

How bloated is the interface? Just because an expression can be almost anything doesn't mean it usually is. But in those cases where it is, perhaps because you can combine search criteria as in your update, then that tilts back to using more abstract methods, at least as helpers.

I personally favor a more specific interface wherever possible

Cheers,
Berryl

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文