具有相同结构和架构但名称不同的两个表需要对一个表进行插入和更新-NHibernate

时间:2019-03-22 22:38:54

标签: c# nhibernate fluent-nhibernate fluent-nhibernate-mapping

我在一个数据库中有两个具有相同结构和架构的不同表。

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()的重载调用

1 个答案:

答案 0 :(得分:1)

有一个鲜为人知/使用过的NHibernate功能,称为“实体名称”,它至少可以在某种程度上使您能够做自己想做的事情。


背景信息:

此功能的介绍可以在这里找到:Mapping the same class to a view and a table using entity-name(也适用于具有相同结构的两个表)。

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(),然后Save()使用所需的EntityName。 (您可能还需要清除对象的ID。)

建议简化操作

我不知道结构相同的两个不同表的设计背景,但是如果您的数据库结构不是一成不变的,则可以只使用一个表employee并添加一列{{ 1}},并将其用作查询的过滤器。将temp更改为EmployeeTemp时,只需要将切换从Employee切换到temp = 1

对于类似的情况,请在此处查看Multiple DB tables for one property in model