C# 如何在NHibernate中获取ParentId可能引用不同表的实体列表

C# 如何在NHibernate中获取ParentId可能引用不同表的实体列表,c#,nhibernate,nhibernate-mapping,C#,Nhibernate,Nhibernate Mapping,我是NHibernate的新手,所以我确信我只是错过了一些基本的东西 我有一个名为Issue的表,它有一个ParentId列。ParentId可以引用不同的表(即Project或Customer等)。如何在NHibernate中执行该查询,以便仅显示属于Project的问题。这是我试过的 DetachedCriteria dCriteria = DetachedCriteria.For<Issue>("issue") .SetProje

我是NHibernate的新手,所以我确信我只是错过了一些基本的东西

我有一个名为Issue的表,它有一个ParentId列。ParentId可以引用不同的表(即Project或Customer等)。如何在NHibernate中执行该查询,以便仅显示属于Project的问题。这是我试过的

            DetachedCriteria dCriteria = DetachedCriteria.For<Issue>("issue")
            .SetProjection(Projections.Property("ParentId"))
            .CreateAlias("Project", "project", NHibernate.SqlCommand.JoinType.InnerJoin)
            .Add(Restrictions.EqProperty("issue.ParentId", "project.Id"))
            ;
        var issues = Session.CreateCriteria<Issue>("issue")
                .Add(Subqueries.Exists(dCriteria)).List<Issue>();
        return issues;
DetachedCriteria=DetachedCriteria.For(“问题”)
.SetProjection(Projections.Property(“ParentId”))
.CreateAlias(“项目”、“项目”、NHibernate.SqlCommand.JoinType.InnerJoin)
.Add(Restrictions.EqProperty(“issue.ParentId”、“project.Id”))
;
var issues=Session.CreateCriteria(“问题”)
.Add(subquerys.Exists(dCriteria)).List();
退货问题;
我的映射看起来像这样。请注意,我没有对父对象的任何引用,因为我不知道它将是什么

    <class name="Issue" table="dbo.Issue" lazy="true">
    <id name="Id" column="Id">
        <generator class="assigned" />
    </id>

    <property name="ParentId" column="ParentId" />

    <property name="Name" />

    <property name="Description" />

我希望得到任何指导。
也许我应该多解释一下。我有一个所有问题的网格,我想显示一个类型列,这样我们就知道什么类型的问题(项目等)。该列除了显示这个问题之外,没有其他用途,所以我认为将其添加到数据库是无效的。在SQL中,通过连接或使用Exists来过滤数据非常容易。在NHibernate中必须有一个类似的方法,这样我就不必在每个项目中循环所有的问题

这是一个可怕的设计。您至少应该为关系或其他列使用不同的列来标识类型或父对象

如果您这样做,您将能够使用NHibernate清晰地映射它

如果你因为某种原因不能,也许你正在寻找一个any映射

  • 您不应该在对象中直接使用外键ID——这是一种以数据为中心的方法。使用NHibernate,您可以使用真实对象或真实对象的集合来表示关系。Nhibernate会自动处理数据库中的外键

  • 我会使用一个接口或基类来表示可以用作父项的不同项,如果您确实需要解决问题,以便有一个指向其父项的链接。但您可能不这样做,因为您很可能会获取例如“客户”,然后反复讨论问题

  • 分配的ID通常是一个坏消息 主意最好使用类似 HiLo或DBs本地人 发电机

  • 例如,您的对象可能如下所示:

    public class Issue
    {
       public int Id{ get; set; }
       public IHazIssues Parent { get; set; } //If you really need this
       public string Name { get; set; }
       public string Description { get; set; }
    }
    
    public class Customer : IHazIssues 
    {
       public int Id{ get; set; }
       public IList<Issue> Issues { get; set; }
       public string NAme{ get; set; }
    }
    
    //If you don't need the parent mapping on Item you don't need this.
    public interface IHazIssues 
    {
       IList<Issue> Issues { get; set; }
    }
    
    公共类问题
    {
    公共int Id{get;set;}
    public ihazisses Parent{get;set;}//如果确实需要
    公共字符串名称{get;set;}
    公共字符串说明{get;set;}
    }
    公共类客户:IHazIssues
    {
    公共int Id{get;set;}
    公共IList问题{get;set;}
    公共字符串名称{get;set;}
    }
    //如果不需要项上的父映射,则不需要此映射。
    公共接口问题
    {
    IList问题{get;set;}
    }
    

    等等。

    像“这是一个可怕的设计”这样的一般性陈述对解决问题并没有真正的效果。如果您描述了任何映射的作用或is@Steven,您当然可以在NHibernate文档中查找
    。以下是Ayende对该功能的概述:Steven,当您无法区分所指的对象类型时,这是一种可怕的设计!那会引起麻烦和混乱!这就是我要找的。我对这种映射方法不熟悉,所以我一直在寻找如何实现的指导。在过去,我避免添加“Type”列,因为类型可以通过数据库连接简单地过滤掉,但这与Ayende在文章中描述的方式是有道理的。感谢Falcon和UpTheCreek为您提供的指导。我已经添加了一些关于我正在努力实现的其他信息。我明白你在这里试图做的事情,但对于我有限的需求来说,这似乎过于复杂了(见上面的附加评论)。是的,通过这种方法,你可以循环处理所有问题,并找出它们所涉及的内容。抱歉,如果这看起来过于复杂,但这就是您使用NHibernate的方式-如果您想采用以数据为中心的方法,为什么要使用它?