简短版本:
在NHibernate中是否可以为数据库中没有相应表的类创建映射,并为数据应该来自的每个属性指定?
长版:
我有以下课程:
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; }
}
}
类Company
是映射到表的普通实体
类Month
是一个没有ID或现有映射的简单类(为简洁起见,删除了构造函数和错误检查):
public class Month
{
public int MonthNumber { get; set; }
public int Year { get; set; }
}
我的数据库有以下两个表:
表TAX_AUDITOR_ALLOWED_COMPANIES
只有一列COMPANY_ID
,它是表COMPANY
的FK,并且具有UNIQUE索引。
表TAX_AUDITOR_ALLOWED_MONTHS
有两列MONTH_NUMBER
和YEAR
。两个列都有一个UNIQUE索引。
我想映射TaxAuditorSettings
,以便我可以向我的NHibernate会话询问此类型的对象,然后NHibernate应将TAX_AUDITOR_ALLOWED_MONTHS
的内容放入列表TaxAuditorSettings.AllowedMonths
和TAX_AUDITOR_ALLOWED_COMPANIES
中引用的公司列入TaxAuditorSettings.AllowedCompanies
列表。
这有可能吗?如果是这样,怎么样?如果没有,你会怎么做呢?
请注意:如果需要,我可以更改数据库。
答案 0 :(得分:2)
不是你要求的但是这里
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();
}
}
注意:如果您可以更改数据库,那么清理表格会更容易和更高效
答案 1 :(得分:2)
我会这样做。
public class MonthMap : ClassMap<Month>{
public MonthMap(){
CompositeId()
.KeyProperty(x=>x.MonthNumber,"MONTH_NUMBER")
.KeyProperty(x=>x.Year);
Table("TAX_AUDITOR_ALLOWED_MONTHS");
}
}
在名为COMPANY
的{{1}}表中添加一列,并将其映射到bool属性。将列更新为1,其中在TaxAuditable
中找到匹配的行。然后删除表TAX_AUDITOR_ALLOWED_COMPANIES
,因为它没有任何实际用途。
现在您有一个公司,其中包含相应的属性,您可以查询公司TAX_AUDITOR_ALLOWED_COMPANIES
TaxAuditable
的位置,并将其与true
一起传递给方法进行工作/计算等等......也许是这样的事情?
Months