C# 是否有必要将实体类复制为视图模型以使用NHibernate?
我很难在MVC5中使用NHibernate。问题是NHibernate需要我的类的C# 是否有必要将实体类复制为视图模型以使用NHibernate?,c#,nhibernate,fluent-nhibernate,asp.net-mvc-5,C#,Nhibernate,Fluent Nhibernate,Asp.net Mvc 5,我很难在MVC5中使用NHibernate。问题是NHibernate需要我的类的Id属性是私有的或受保护的,但是MVC模型绑定器无法在现有实体上设置Id,因此NHibernate将其视为新记录,并插入它而不是编辑它 public interface IEntity { int Id {get; } } public class User : IEntity { public virtual int Id {get; protected set;} public vir
Id
属性是私有的或受保护的,但是MVC模型绑定器无法在现有实体上设置Id,因此NHibernate将其视为新记录,并插入它而不是编辑它
public interface IEntity
{
int Id {get; }
}
public class User : IEntity
{
public virtual int Id {get; protected set;}
public virtual string Email {get; set;}
public virtual DateTime? LastLogin {get; set;}
}
这个很好用
public JsonResult SaveUser(User user)
{
var userModel = new UserModel();
if(userModel.SaveUser(user)) return Json(new {success = true});
return Json(new {success = false});
}
这会失败,因为Id
有一个受保护的集,这是NHibernate实体所必需的。因此,由于MVC模型绑定器无法设置Id
,NHibernate将其视为一个新实体
public JsonResult EditUser(User user)
{
var userModel = new UserModel();
userModel.EditUser(user);
}
所以看起来我基本上需要将实体类复制为视图模型,但这看起来非常乏味(更不用说反干燥)。这两个类之间的唯一区别是视图模型类具有可公开设置的Id
。通过使用,我可以稍微减少tedius,但是看起来我仍然需要将我的类复制为视图模型。它确实有一个从dynamic
映射的功能,但这仍然不允许我为现有实体正确设置Id
那么,我是不是遗漏了什么?有没有一种方法可以做到这一点,而不必创建两个几乎相同的类?除非您在模型或视图模型中做一些有趣的事情,或者使用延迟加载,否则您不一定需要创建视图模型。我总是使用
NHibernate
models类,如果我需要一些特殊的模型,而不是精确的模型,那么我会创建单独的视图模型。例如,登录
是使用视图模型执行的,因为密码有一些晶体学和安全选项。除此之外,我使用默认ASP.Net MVC模型绑定器的帮助,我的编辑功能通常如下所示-
意见-
@model ConsoleUser
<h2>Create</h2>
@Html.HiddenFor(x=>Model.Id)
......
@Html.EditorFor(x=>Model.UserName)
得到-
/// <summary>
/// Edits this instance.
/// </summary>
/// <returns></returns>
[ValidateInput(false)]
public virtual async Task<ActionResult> Edit(string id)
{
var item = (await _domainService.Get(x => x.Id == id)).FirstOrDefault();
if (item.IsNotNull())
return View(item);
throw new CodedException("E.102.3");
}
在save方法中,它看起来是这样的-
public static void Save<T>(T entity, ISession _session = null, IList<Exception> errors = null) where T : IDomainEntity
{
if (_session == null)
{
using (var session = OpenEngineSession())
using (var trans = session.BeginTransaction())
{
try
{
session.SaveOrUpdate(entity);
trans.Commit();
}
catch (Exception e)
{
errors = errors ?? new List<Exception>();
errors.Add(e);
trans.Rollback();
}
}
}else
{
_session.SaveOrUpdate(entity);
}
}
publicstaticvoidsave(T entity,ISession\u session=null,IList errors=null),其中T:IDomainEntity
{
如果(_session==null)
{
使用(var session=OpenEngineSession())
使用(var trans=session.BeginTransaction())
{
尝试
{
会话。保存或更新(实体);
trans.Commit();
}
捕获(例外e)
{
错误=错误??新列表();
添加(e);
trans.Rollback();
}
}
}否则
{
_会话。保存或更新(实体);
}
}
仅此而已
NHibernate
有一个内置功能,即如果您使用通过NHibernate获取对象,它将保留一个引用,并将自动运行更新查询,而不是插入。除非您在模型或视图模型中做了一些有趣的事情,或者使用延迟加载,否则您不一定需要创建视图模型。我总是使用NHibernate
models类,如果我需要一些特殊的模型,而不是精确的模型,那么我会创建单独的视图模型。例如,登录
是使用视图模型执行的,因为密码有一些晶体学和安全选项。除此之外,我使用默认ASP.Net MVC模型绑定器的帮助,我的编辑功能通常如下所示-
意见-
@model ConsoleUser
<h2>Create</h2>
@Html.HiddenFor(x=>Model.Id)
......
@Html.EditorFor(x=>Model.UserName)
得到-
/// <summary>
/// Edits this instance.
/// </summary>
/// <returns></returns>
[ValidateInput(false)]
public virtual async Task<ActionResult> Edit(string id)
{
var item = (await _domainService.Get(x => x.Id == id)).FirstOrDefault();
if (item.IsNotNull())
return View(item);
throw new CodedException("E.102.3");
}
在save方法中,它看起来是这样的-
public static void Save<T>(T entity, ISession _session = null, IList<Exception> errors = null) where T : IDomainEntity
{
if (_session == null)
{
using (var session = OpenEngineSession())
using (var trans = session.BeginTransaction())
{
try
{
session.SaveOrUpdate(entity);
trans.Commit();
}
catch (Exception e)
{
errors = errors ?? new List<Exception>();
errors.Add(e);
trans.Rollback();
}
}
}else
{
_session.SaveOrUpdate(entity);
}
}
publicstaticvoidsave(T entity,ISession\u session=null,IList errors=null),其中T:IDomainEntity
{
如果(_session==null)
{
使用(var session=OpenEngineSession())
使用(var trans=session.BeginTransaction())
{
尝试
{
会话。保存或更新(实体);
trans.Commit();
}
捕获(例外e)
{
错误=错误??新列表();
添加(e);
trans.Rollback();
}
}
}否则
{
_会话。保存或更新(实体);
}
}
仅此而已
NHibernate
具有内置功能,从某种意义上说,如果您使用通过nhibernate获取对象,它将保留一个引用,并将自动运行更新查询而不是插入。我建议使用MVC特定的视图模型,因为nhibernate模型通常实现动态代理,并且无法序列化为XML/JSON/等。它们可用于在视图中填充数据,但如果某些属性延迟加载数据,则会导致问题
视图模型可以接近数据模型类,但通常它们更特定于需要在屏幕上显示的内容。我建议使用特定于MVC的视图模型,因为NHibernate模型通常实现动态代理,不能序列化为XML/JSON/等。它们可用于在视图中填充数据,但如果某些属性延迟加载数据,则会导致问题
视图模型可以接近数据模型类,但通常它们更特定于需要在屏幕上显示的内容。NHibernate不需要Id是私有的或受保护的,您是从哪里得到这个想法的?假设它是一个自动递增的标识,将其设置为私有是一个很好的做法,但这不是必需的。使用视图模型是可选的,但从开发和应用程序安全的角度来看,这都是一个非常好的实践。例如,使用视图模型可以避免大规模分配攻击:NHibernate不需要Id是私有的或受保护的,您是从哪里得到这个想法的?假设它是一个自动递增的标识,将其设置为私有是一个很好的做法,但这不是必需的。使用视图模型是可选的,但从开发和应用程序安全的角度来看,这都是一个非常好的实践。例如,使用view mod