我有两个不同的表,在一个数据库中具有相同的结构和模式。
Comp.Employee
Comp.EmployeeTemp
实体类:
public class Employee
{
public virtual string Name {get;set;}
}
NHibernate流畅的映射:
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和流畅的映射中做到这一点?
更新:更新了我的问题以包含EmployeeTempMap
映射和重载调用SaveOrUpdate()
有一个很少知道/使用的NHibernate功能称为“实体名称”,它可以让你做你想做的事情 - 至少在某种程度上。
背景资料:
可以在此处找到该功能的介绍:Mapping the same class to a view and a table using entity-name(也适用于具有相同结构的两个表)。
流畅的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);
但是,我还没有确认你的目标(不必将Employee“转换”为EmployeeTemp)可以实现这一点,因为NHibernate在使用EntityName EmployeeTemp
加载对象并尝试使用EntityName Employee
保存时可能会抛出错误。您可能需要从会话中手动Evict()
它,然后Save()
它与所需的EntityName。 (您可能还需要清除对象的ID。)
建议简化:
我不知道具有相同结构的两个不同表的设计背景,但是如果您的数据库结构没有一成不变,您可以简单地使用一个表employee
并添加一列temp
并将其用作过滤器查询。将EmployeeTemp
更改为Employee
时,您只需将temp = 1
切换到temp = 0
。
对于类似的案例,请查看SO:Multiple DB tables for one property in model