我在一个数据库中有两个不同的表,具有相同的结构和模式。
Comp.Employee
Comp.EmployeeTemp实体类:
public class Employee
{
public virtual string Name {get;set;}
}NHibernate fluent映射:
public class EmployeeMap : ClassMap<Employee>
{
public EmployeeMap()
{
Map(x => Name);
}
}
public class EmployeeTempMap : ClassMap<Employee>
{
public EmployeeTempMap()
{
Map(x => Name);
}
}
var manager = new Employee { Name = "Tom"}
Session().SaveOrUpdate("EmployeeTemp", manager)我想将manager实体保存到Comp.EmpoyeeTemp表,而不是Comp.Employee。我需要能够同时写入两个表,但不能同时使用相同的Employee实体。如何在NHibernate和fluent映射中做到这一点?
更新:更新了我的问题,包括EmployeeTempMap映射和对SaveOrUpdate()的重载调用
发布于 2019-03-23 19:20:22
有一个鲜为人知的/使用过的NHibernate特性叫做“实体名称”,它可能使您能够做您想要做的事情--至少在某种程度上是这样。
背景信息:
在这里可以找到对该特性的介绍:使用实体名称将同一个类映射到视图和表。 (也适用于结构相同的两个表)。
Fluent NHibernate也支持这个特性,如源代码:fluent nhibernate ClassMap中所示。
以上链接中的相关代码:
/// <summary>
/// Specifies an entity-name.
/// </summary>
/// <remarks>See http://nhforge.org/blogs/nhibernate/archive/2008/10/21/entity-name-in-action-a-strongly-typed-entity.aspx</remarks>
public void EntityName(string entityName)
{
attributes.Set("EntityName", Layer.UserSupplied, entityName);
}免责声明:(以下代码未经测试,但应该会使您走上正确的轨道。当某件事出错或丢失时,可以随意编辑)
正如我在对上述问题的评论中所提到的,您可以对类映射使用继承(缩写为示例):
// Base class
public class BaseEmployeeMap<T> : ClassMap<T> where T : Employee
{
public BaseEmployeeMap()
{
Map(p => p.Name);
// add all Properties that are common to both Employee and EmployeeTemp
}
}
// Mapping for Employee
public class EmployeeMap : BaseEmployeeMap<Employee>
{
public EmployeeMap() : base()
{
EntityName("Employee");
}
}
// Mapping for EmployeeTemp
public class EmployeeTempMap : BaseEmployeeMap<Employee>
{
public EmployeeTempMap() : base()
{
EntityName("EmployeeTemp");
}
} 现在您可以通过使用重载的方法并提供EntityName来查询和插入项。
// both tempEmployee and employee will be instances of class "Employee"
var tempEmployee = session.Get("EmployeeTemp", id);
var employee = session.Get("Employee", id);
session.SaveOrUpdate("EmployeeTemp", tempEmployee);
session.SaveOrUpdate("Employee", employee);但是,我还没有验证您的目标(不需要将员工“转换”为EmployeeTemp)是否可以实现,因为NHibernate可能会在用EntityName EmployeeTemp加载对象并试图用EntityName Employee保存对象时抛出错误。您可能需要手动从会话中Evict()它,然后使用所需的EntityName对它进行Save()。(您可能还需要清除对象的ID。)
使事情变得更简单的建议:
我不知道具有相同结构的两个不同表的设计背景,但是如果数据库结构不是固定的,您可以使用一个表employee并添加一个列temp,并将其用作查询的筛选器。当将EmployeeTemp更改为Employee时,只需将开关从temp = 1切换到temp = 0即可。
关于类似的情况,请看这里的SO:模型中一个属性的多个DB表
https://stackoverflow.com/questions/55308680
复制相似问题