I have two different tables with the same structure and schema in one database.
Comp.Employee
Comp.EmployeeTemp
Entity class:
public class Employee
{
public virtual string Name {get;set;}
}
NHibernate fluent mapping:
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)
I want to save the manager
entity to Comp.EmpoyeeTemp
table and not to Comp.Employee
. I need to be able write to both tables but not at the same time using the same Employee
entity.
How can I do this in NHibernate and fluent mapping?
Update:
Updated my question to include the EmployeeTempMap
mapping and the overloaded call to SaveOrUpdate()
There is a rarely known/used NHibernate feature called "entity-name", which might enable you to do what you are trying to do - at least to some degree.
Background information:
An introduction to the feature can be found here: Mapping the same class to a view and a table using entity-name (also applies to two tables with the same structure).
Fluent NHibernate also supports this feature, as can be seen in the source: fluent-nhibernate ClassMap
Relevant code from the above link:
/// <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);
}
Disclaimer: (the following code is untested but should put you on the right track. Feel free to edit when something is wrong or missing)
As mentioned in my comment to your question above, you can use inheritance for the class mappings like this (shortened example):
// 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");
}
}
Now you can query and insert items by using the overloaded methods and supplying the 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);
However, I have not verified that your goal (not having to "convert" an Employee to EmployeeTemp) can be achieved with this, because NHibernate might throw an error when loading the object with EntityName EmployeeTemp
and trying to save it with the EntityName Employee
. You might need to manually Evict()
it from the session and then Save()
it with the desired EntityName. (You might also need to clear the ID of the object.)
Suggestion to make things simpler:
I don't know the background of the design for two different tables with the same structure, but if your database structure is not set in stone, you could simply use one table employee
and add a column temp
and use that as a filter for your queries. When changing an EmployeeTemp
to an Employee
you would only have to flip the switch from temp = 1
to temp = 0
.
For a similar case look here on SO: Multiple DB tables for one property in model