Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/313.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 通过自定义字符串从存储库中获取实体_C#_Nhibernate_Orm_Asp.net Mvc 2 - Fatal编程技术网

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

C# 通过自定义字符串从存储库中获取实体,c#,nhibernate,orm,asp.net-mvc-2,C#,Nhibernate,Orm,Asp.net Mvc 2,使用简单字符串作为查询参数从数据库查询实体的良好实践。谁应该实现将字符串“转换”为实体的方法,谁应该调用此方法?存储库、实体或其他对象,比如MVC应用程序中的控制器 关于一个更具体的例子,我有一个ASP.NET MVC 2应用程序,使用了夏普体系结构的IRepository和SharpModelBinder。后者的配置是这样的,如果用户提交了一个表单,该表单的ID代替了一个对象,那么它将查询具有相同ID的对象的相应存储库。我想添加到这个示例中,以便不仅能够使用ID,还能够使用自定义字符串。当然,

使用简单字符串作为查询参数从数据库查询实体的良好实践。谁应该实现将字符串“转换”为实体的方法,谁应该调用此方法?存储库、实体或其他对象,比如MVC应用程序中的控制器

关于一个更具体的例子,我有一个ASP.NET MVC 2应用程序,使用了夏普体系结构的
IRepository
SharpModelBinder
。后者的配置是这样的,如果用户提交了一个表单,该表单的ID代替了一个对象,那么它将查询具有相同ID的对象的相应存储库。我想添加到这个示例中,以便不仅能够使用ID,还能够使用自定义字符串。当然,对于每个存储库/实体,从通用查询字符串获取具体ID的方法是不同的。我该怎么做

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

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

class Patient : Entity {
    // some properties, constructor, etc.
}
现在,如果我有一个医生实体编辑器(比如表单),我可以输入一个ID来代替
Doctor.ActualPatient
,模型绑定器将负责分配适当的对象。但是如果用户输入一个自定义字符串(如
患者的姓名
),该怎么办

以下是我目前的选择:

  • 控制器应处理此自定义字符串。因此,当ModelBinder无法将
    患者
    绑定到
    医生
    (=对于
    患者
    ,返回
    null
    )后,控制器获取字符串,并使用某种算法尝试获取由该字符串表示的患者(或者也失败)
  • 控制器负责这一点,但调用的方法是在控制器类以外的其他地方定义的(请看下一个问题)
  • ModelBinder应配置为使用此外部方法
  • 你不应该做这样的事,这总是被认为是不好的做法
  • 其他事项(欢迎提出建议)
  • 以下是我对该方法应在何处实施的建议:

  • 存储库应该有一个
    GetEntityFromAString(string)
    方法,该存储库的子类应该重新定义该方法
  • 实体应该有一个属性,如果存在该属性,该属性将负责此转换,控制器/modelbinder/etc将检查该属性并调用类似于
    getEntityFromAstringingThisRepository(string,repository)
  • 我已经说过这是一种不好的做法
  • 别的
  • 虽然具体的例子是针对Sharp Architecture/ASP.NET MVC2/NHibernate的,但请随意回答


    谢谢你的回答。

    我会从控制器中明确地管理它

    如果按ID绑定,则可以保证获得实例,如果找不到实例,则为null。但是由任意属性绑定并不是那么简单:如果有多个匹配怎么办?活页夹是否应该抛出异常?它应该只返回第一个结果吗?正如您所看到的,很容易遇到意外的结果,从而违反了规则

    如果你真的知道你在做什么,并且你想要这个,我会创建一个带有关联属性的自定义绑定器,它将具有用于查找实体的属性的名称,例如

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

    听起来像是社区维基……是的,但是通过添加逻辑(例如,您实际说的存储库类),存储库应该知道如何处理这种情况。还是说存储库不应该包含这样的逻辑?添加诸如搜索哪个属性之类的内容也不好,因为可能会检查多个属性。如何将字符串“转换”为实体的逻辑可能要复杂得多,这实际上可能需要大量查询数据库。@SztupY:我不确定我是否理解你的意思。。。当然,实际的获取是委托给存储库的。如果您需要比这更复杂的东西,那么您肯定不想在活页夹中这样做,就像我在回答的开头所说的。是的,但是活页夹实际上是在调用存储库来获取ID。如果它可以使用存储库的“getID”方法,为什么不能使用另一种方法,比如“GetEntityFromName”?为什么将此调用委托给控制器是一个坏主意,但在modelbinder中保持ID获取是一个好主意?我在控制器中执行此操作比在binder中执行此操作更明确。活页夹是一段更可重用的代码,但正如我所说的,这种查找有许多可能的行为,因此当它的行为与您所认为的不一样时,您最终会感到不快。