C# 具有不带ID的表的复杂映射
简短版本: 在NHibernate中,是否可以为数据库中没有对应表的类创建映射,并为每个属性指定数据应该来自哪里 长版本: 我有以下课程:C# 具有不带ID的表的复杂映射,c#,nhibernate,fluent-nhibernate,C#,Nhibernate,Fluent Nhibernate,简短版本: 在NHibernate中,是否可以为数据库中没有对应表的类创建映射,并为每个属性指定数据应该来自哪里 长版本: 我有以下课程: public class TaxAuditorSettings { private readonly IList<Month> _allowedMonths = new List<Month>(); private readonly IList<Company> _allowedVgs = new List
public class TaxAuditorSettings
{
private readonly IList<Month> _allowedMonths = new List<Month>();
private readonly IList<Company> _allowedVgs = new List<Company>();
public IList<Month> AllowedMonths
{
get { return _allowedMonths; }
}
public IList<Company> AllowedVgs
{
get { return _allowedVgs; }
}
}
我的数据库有以下两个表:
表TAX\u AUDITOR\u ALLOWED\u companys只有一个列COMPANY\u ID,该列是表COMPANY的FK,并且具有唯一索引
表TAX\u AUDITOR\u ALLOWED\u MONTHS有两列MONTH\u NUMBER和YEAR。有一个横跨两列的唯一索引
我想映射TaxAuditorSettings,这样我就可以向我的NHibernate会话请求此类对象,然后NHibernate应该将TAX_AUDITOR_ALLOWED_MONTHS的内容放入TaxAuditorSettings.AllowedMonths列表,并将TAX_AUDITOR_ALLOWED_Companys中引用的公司放入TaxAuditorSettings.AllowedCompanys列表
这可能吗?如果是,怎么做?如果不是,你会怎么做
请注意:如有必要,我可以更改数据库。不完全符合您的要求,但现在开始
public TaxAuditorSettings GetAuditorSettings(ISession session)
{
// assuming there is a ctor taking the enumerables as parameter
return new TaxAuditorSettings(
session.CreateSQLQuery("SELECT MONTH_NUMBER, YEAR FROM TAX_AUDITOR_ALLOWED_MONTHS")
.SetResultTransformer(new MonthResultTransformer())
.Future<Month>(),
session.CreateCriteria<Company>()
.Add(NHibernate.Criterion.Expression.Sql("Id IN (SELECT COMPANY_ID FROM TAX_AUDITOR_ALLOWED_COMPANIES)"))
.Future<Company>())
}
class MonthResultTransformer : IResultTransformer
{
public IList TransformList(IList collection)
{
return collection;
}
public object TransformTuple(object[] tuple, string[] aliases)
{
return new Month
{
MonthNumber = (int)tuple[0],
Year = (int)tuple[1],
}
}
}
更新:保存
public void SaveOrUpdate(ISession session, TaxAuditorSettings settings)
{
using (var tx = session.BeginTransaction())
{
// get whats in the database first because we dont have change tracking
var enabledIds = session
.CreateSqlQuery("SELECT * FROM TAX_AUDITOR_ALLOWED_COMPANIES")
.Future<int>();
var savedMonths = session
.CreateSQLQuery("SELECT MONTH_NUMBER, YEAR FROM TAX_AUDITOR_ALLOWED_MONTHS")
.SetResultTransformer(new MonthResultTransformer())
.Future<Month>();
foreach (var id in settings.AllowedVgs.Except(enabledIds))
{
session.CreateSqlQuery("INSERT INTO TAX_AUDITOR_ALLOWED_COMPANIES Values (:Id)")
.SetParameter("id", id).ExecuteUpdate();
}
foreach (var month in settings.AllowedMonths.Except(savedMonths))
{
session.CreateSqlQuery("INSERT INTO TAX_AUDITOR_ALLOWED_MONTHS Values (:number, :year)")
.SetParameter("number", month.Number)
.SetParameter("year", month.Year)
.ExecuteUpdate();
}
tx.Commit();
}
}
注意:如果您可以更改数据库,那么清理表将更容易,也更高效我会这样做
public class MonthMap : ClassMap<Month>{
public MonthMap(){
CompositeId()
.KeyProperty(x=>x.MonthNumber,"MONTH_NUMBER")
.KeyProperty(x=>x.Year);
Table("TAX_AUDITOR_ALLOWED_MONTHS");
}
}
谢谢你能指出它和我问的有什么不同吗?是因为我不能执行session.Get,但必须执行GetAuditorSettingssession吗?还有什么不同吗?你不能执行session.SaveOrUpdatesettings,你必须执行SaveOrUpdatesession,settings如果你能更改数据库,标记答案看起来会更好如果你仍然可以提供保存的实现,那就太好了,我会接受你的答案。谢谢。我将考虑相应地更改数据库。
public class MonthMap : ClassMap<Month>{
public MonthMap(){
CompositeId()
.KeyProperty(x=>x.MonthNumber,"MONTH_NUMBER")
.KeyProperty(x=>x.Year);
Table("TAX_AUDITOR_ALLOWED_MONTHS");
}
}
var taxAuditableCompanies = session.QueryOver<Company>()
.Where(x=>x.TaxAuditable==true).Future();
var months=session.QueryOver<Month>().Future();
var myService = new MyService();
myService.DoSomeWork(taxAuditableCompanies, months);