【问题标题】:How to map NHibernate variable table reference?如何映射 NHibernate 变量表引用?
【发布时间】:2015-06-30 05:57:28
【问题描述】:

有一个名为 ChildTable 的表,其中包含 2 列 SourceTableSourceId 以及其他一些表 ParentTable1ParentTable2 等。

SourceTable 具有与父表关联的值(1 -> ParentTable1、2 -> ParentTable2)时,在 SourceId 中找到的 Id 可用于连接到父表。例如,要获取与ParentTable1 中的行相关联的所有ChildTable 行,可以使用以下查询来实现:

select *
from ChildTable ct
join ParentTable1 pt1
  on ct.SourceTable = 1 and ct.SourceId = pt1.Id

我想将这 2 个 ChildTable 列映射为每个父表的 1 个属性:Parent1、Parent2...,因此其中 1 个不为空,其余的父属性为空:

public class ChildClass
{
    public Parent1Class Parent1 { get; set; }
    public Parent2Class Parent2 { get; set; }
    public Parent3Class Parent3 { get; set; }
    .
    .
    .
}

问题是:这种情况下的映射怎么写(可能的话用代码映射)?

注意:这是为了映射现有表,重构表模式还不是解决方案(但欢迎提出建议)。

更新

出于查询的目的,将 ChildClass 属性 Parent1 映射为:

ManyToOne(property => property.Parent1, map => map.Formula("(select pt1.Id from dbo.ParentTable1 pt1 where SourceTable = 1 and pt1.Id = SourceId)"));

和 Parent1Class 的 Children 集合:

mapper.Where("SourceTable = 1");

对于更新/插入,它可能可以使用访问器来实现,稍后会发布更新。

【问题讨论】:

  • 在你想要的 ChildClass 中是 Parent1Class 类型的所有属性,还是 Parent1/2/3Class?
  • 啊,谢谢你的注意,这是一个错字,它们是不同的类型。
  • 您有一个条件,您希望使用 where 子句过滤多对一映射 - 基于 SourceId。你能确认 SourceIds 是固定的吗?似乎有一个未解决的jira
  • 该问题似乎正在寻找解决我问题的方法。 SourceId 被修复是什么意思?
  • SourceId 列中可以有重复值,但对于每个SourceTable,它们必须是唯一的。基本上SourceTableSourceId 的组合是独一无二的。如果每个 SourceId 指向不同的父表(ParentTable1、ParentTable2、ParentTable3),则可以让 SourceId = 1 用于 3 行

标签: c# nhibernate nhibernate-mapping


【解决方案1】:

为什么不使用Any

类:

public class ChildClass
{
    public virtual ParentBase Parent { get; set; }

    // beware of proxies when casting... this may not work like this
    public Parent1Class Parent1 { get { return Parent as Parent1Class; } }
    public Parent2Class Parent2 { get { return Parent as Parent2Class; } }
    .
    .
    .
}

映射:

Any(x => x.Parent, typeof(int), m =>
{
    m.IdType<int>();
    m.MetaType<int>();

    m.MetaValue(1, typeof(Parent1));
    m.MetaValue(2, typeof(Parent2));

    m.Columns(
      id => id.Name("SourceId"), 
      classRef => classRef.Name("SourceTable"));
});

还有many-to-any,它将任何类型的集合映射到关系表中。

在查询中使用时,可以查看.class,或者使用子查询:

HQL:

select *
from ChildTable ct join Parent
where pt1.class = Parent1

select * 
from ChildTable ct 
Where ct.Parent in (from Parant2 p where p.Property = 'Hugo')

【讨论】:

  • 谢谢。使用child.Parent is Parent1Class 更新父属性并使用LINQ 进行查询是可行的。无法让.Fetch(_ =&gt; _.Parent) 工作,因为它会抛出NHibernate.dll 中出现“System.InvalidCastException”类型的异常,但未在用户代码中处理。附加信息:无法将“NHibernate.Type.AnyType”类型的对象转换为“NHibernate.Type.ComponentType”类型。使用.Select(...) 进行投影的相同错误。可能会发布另一个问题。
  • 在尝试使用 cast/as 以在 LINQ Where 子句中对 Parent 设置条件时,出现与上述相同的问题。
  • 嗨@RăzvanFlaviusPanda 你能解决这个演员表问题吗?
猜你喜欢
  • 2012-12-09
  • 1970-01-01
  • 1970-01-01
  • 2012-01-04
  • 1970-01-01
  • 2012-04-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多