c# - 具有相同结构和模式但名称不同的两个表需要插入和更新一个表 - NHibernate
问题描述
我在一个数据库中有两个具有相同结构和模式的不同表。
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
table 而不是Comp.Employee
. 我需要能够写入两个表,但不能同时使用同一个Employee
实体。我怎样才能在 NHibernate 和流利的映射中做到这一点?
更新:
更新了我的问题以包括EmployeeTempMap
映射和对 SaveOrUpdate() 的重载调用
解决方案
有一个鲜为人知/使用过的 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);
但是,我尚未验证您的目标(不必将 Employee 转换为 EmployeeTemp)可以通过此实现,因为 NHibernate 在使用 EntityName 加载对象EmployeeTemp
并尝试使用 EntityName 保存它时可能会引发错误Employee
。您可能需要Evict()
从会话中手动操作,然后Save()
使用所需的 EntityName。(您可能还需要清除对象的 ID。)
让事情变得更简单的建议:
我不知道具有相同结构的两个不同表的设计背景,但是如果您的数据库结构不是一成不变的,您可以简单地使用一个表employee
并添加一列temp
并将其用作查询的过滤器。将 an 更改EmployeeTemp
为 an 时,Employee
您只需将开关从temp = 1
to翻转temp = 0
。
对于类似的情况,请查看 SO:Multiple DB tables for one property in model
推荐阅读
- azure-ad-b2c - Azure AD B2C 电话 OTP 验证
- lua - LUA:#table 键引用突然改变表条目
- python - 在每个 X 循环中使用 Python 和 Pandas 保存到 excel
- php - 根据来自另一个数组的二进制值从一个数组中选择一个或多个值
- gitlab - 如何在 Gitlab 中为 Java 设置代码质量插件?
- python - 熊猫时间增量只有小时分钟和秒
- html - 引导 Vue 和 Axios
- javascript - 如何在没有消息对象 Discord.js 的情况下向特定频道发送消息
- python - 如何使用Django删除表中的一行
- android - 单击 Item Inside recycler 视图时,如何在 viewpager2 中膨胀它们各自的片段?