通过自定义字符串从存储库获取实体

问题描述:

使用简单字符串作为查询参数来查询数据库实体的好做法被认为是一种良好做法。谁应该实现将字符串“转换”为实体的方法,以及谁应该调用此方法?存储库,实体或其他对象,就像MVC应用程序中的控制器一样?通过自定义字符串从存储库获取实体

对于更具体的例子,我有一个ASP.NET MVC 2应用程序,使用Sharp Architecture的IRepositorySharpModelBinder。后者的配置是这样的,即如果用户提交了一个表单,该表单有一个ID代替一个对象,那么它将查询具有相同ID的对象的相应存储库。我想添加到这个例子不仅能够使用一个ID,但也是一个自定义字符串。当然,从通用查询字符串获取具体ID的方法对于每个Repository/Entity都是不同的。我应该怎么做?

更加具体。假设我有两个实体:

class Doctor : Entity { 
    public virtual Patient ActualPatient { get; set; }; 
    // some other properties, constructor, etc. 
} 

class Patient : Entity { 
    // some properties, constructor, etc. 
} 

现在,如果我对医生实体的编辑器(如表格),我可以代替Doctor.ActualPatient的输入ID和模型绑定将采取分配的护理适当的对象。但是如果用户输入一个自定义字符串(如Patient的名称)呢?

这里是我目前的选择:

  1. 控制器应借此自定义字符串的照顾。所以后ModelBinder的不能结合的PatientDoctor(=用于Patient返回null)时,控制器采取串和使用一些algorythm它会尝试获取由该字符串表示的患者(或失败太)
  2. 该控制器负责的这一点,但要求被定义别的地方不是在控制器类中的方法(看下一题)
  3. 的ModelBinder的应配置为使用这个外部方法
  4. 你不应该这样做这,这总是被认为是不好的做法
  5. 别的东西(建议,欢迎)

而且这里是我在哪里此方法应执行的建议:

  1. 存储库应该有一个GetEntityFromAString(string)方法,并为这个仓库的子类应该重新定义此方法。
  2. 实体应该有一个属性,如果目前负责这个转换,以及控制器/模型绑定器的/ etc这个属性的检查,并呼吁像GetEntityFromAStringUsingThisRepository(string,repository)
  3. 的方法我已经说过,这是一个不好的做法
  4. 别的东西

虽然具体的例子是夏普建筑/ ASP.NET MVC2/NHibernate的随​​意普遍回答。

感谢您的答案。

+0

听起来社区维基... – RedFilter 2010-04-30 14:56:30

+0

你为什么这么认为? – SztupY 2010-04-30 15:23:49

我会明确地从控制器管理这个。

如果通过ID进行绑定,则可以保证您将获得实例,如果未找到,则可以为null。但是,绑定任意属性并不那么简单:如果有多个匹配,会怎么样?绑定器应该抛出异常吗?它应该只返回第一个结果吗?正如你所看到的,很容易遇到意想不到的结果,因此违反了principle of least astonishment

如果你真的知道你在做什么,你想要这个,我想创建一个与相关属性的定制绑定,这将有属性的名称使用查找实体,例如

class Patient { 
    int Id {get;set;} 
    string PatientName {get;set;} 
} 
... 
ActionResult SomeAction([MyCustomBinder("PatientName")] Patient patient) {...} 
+0

是的,但是通过将例如逻辑添加到您实际上正在说的Repository类中,知识库应该知道如何处理这种情况。还是你说存储库不应该包含这样的逻辑?添加诸如要搜索哪个属性的东西也不好,因为可能会检查多个属性。如何将字符串“转换”为实体的逻辑可能要复杂得多,这可能实际上需要查询数据库。 – SztupY 2010-04-30 20:40:11

+0

@SztupY:我不确定我是否理解你在说什么......当然,实际的提取是委托给Repository的。如果你需要比这更复杂的东西,那么你肯定*不想在活页夹中做这件事,就像我在回答开始时所说的那样。 – 2010-04-30 21:24:49

+0

是的,但活页夹实际上是调用存储库来获取ID。如果它可以使用存储库的“getID”方法,为什么不能使用另一种方法,比如“GetEntityFromName”呢?为什么将这个调用委托给控制器是一个不好的主意,但是将模型绑定器中的ID保存到一个好的? – SztupY 2010-04-30 21:43:49