0

我的数据库中有一个联结表。我需要读取 id 值并在我的程序中使用它们。我无法让 NHibernate 返回数据库中的任何记录。看起来好像我的映射文件“编译”了,但没有返回任何结果。

链接表

  • int id_ObjectA (外键)
  • int id_ObjectB (外键)

LinkDAO 类:

public class LinkDAO
{
    public virtual ObjectADAO ObjectA { get; set; }
    public virtual ObjectBDAO ObjectB { get; set; }

    public override bool Equals(object obj)
    {
        if (obj == null)
        {
            return false;
        }
        var t = obj as LinkDAO;
        if (t == null)
        {
            return false;
        }
        return (t.ObjectA == ObjectA && t.ObjectB == ObjectB);
    }

    public override int GetHashCode()
    {
        return (ObjectA.Name + "|" + ObjectB.Name).GetHashCode();
    }
}

映射文件“LinkDAO.hbm.xml”:

<class name="LinkDAO" table="LinkTable" lazy="false">
    <composite-id>
      <key-property name="ObjectA" column="id_ObjectA" />
      <key-property name="ObjectB" column="id_ObjectB" />
    </composite-id>
</class>

我这样查询:

IList<LinkDAO> links  =
        NHibernateContext.Current().Session.QueryOver<LinkDAO>().List();
//Empty list is returned, but I can check the DB and see records 

问题: 当表仅包含复合键时,如何将两列读取为 int 值?(引用实际对象会很有用,但 int id 就足够了)

4

1 回答 1

1

我将 LinkDAO 类设为 Serializable 。

不确定您是否打算使用 ObjectADAO 和 ObjectBDAO 并且是这样的:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication3.Models
{
    [Serializable]
    public class ObjectADAO
    {
        public virtual int Id { get; set; }
        public virtual string Name { get; set; }
    }

    [Serializable]
    public class ObjectBDAO
    {
        public virtual int Id { get; set; }
        public virtual string Name { get; set; }
    }
}

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
                   assembly="ConsoleApplication3"
                   namespace="ConsoleApplication3.Models">

  <class name="ObjectADAO">
    <id name="Id" type="Int32" generator="native"/>
    <property name="Name" />
  </class>

</hibernate-mapping>

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
                   assembly="ConsoleApplication3"
                   namespace="ConsoleApplication3.Models">

  <class name="ObjectBDAO">
    <id name="Id" type="Int32" generator="native"/>
    <property name="Name" />
  </class>

</hibernate-mapping>

您的 LinkDAO.hbm.xml 中似乎有一些拼写错误。我的版本如下:

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2"
                   assembly="ConsoleApplication3"
                   namespace="ConsoleApplication3.Models">

  <class name="LinkDAO" table="LinkTable" lazy="false">
    <composite-id>
      <key-many-to-one name="ObjectA" class="ObjectADAO" column="id_ObjectA"/>
      <key-many-to-one name="ObjectB" class="ObjectBDAO" column="id_ObjectB"/>
    </composite-id>
  </class>
</hibernate-mapping>

测试将正确打印:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using ConsoleApplication3.Models;
using NHibernate.Cfg;
using NHibernate.Tool.hbm2ddl;


namespace ConsoleApplication3
{
    class Program
    {

        static void Main(string[] args)
        {
            var cfg = new Configuration();
            cfg.Configure();
            cfg.AddAssembly(typeof(LinkDAO).Assembly);

            new SchemaExport(cfg).Execute(script: true, export: true, justDrop: true);
            new SchemaExport(cfg).Execute(script:true, export:true, justDrop:false);

            var objAs = new ObjectADAO[] { new ObjectADAO { Name = "A1" }, new ObjectADAO { Name = "A2" } };
            var objBs = new ObjectBDAO[] { new ObjectBDAO { Name = "B1" }, new ObjectBDAO { Name = "B2" } };

            using (var _sessionFactory = cfg.BuildSessionFactory())
            {
                using (var session = _sessionFactory.OpenSession())
                {
                    using (var tran = session.BeginTransaction())
                    {
                        objAs.ToList().ForEach(x => session.Save(x));
                        objBs.ToList().ForEach(x => session.Save(x));
                        tran.Commit();
                    }

                    using (var tran = session.BeginTransaction())
                    {
                        session.Save(new LinkDAO { ObjectA = objAs[0], ObjectB = objBs[1] });
                        session.Save(new LinkDAO { ObjectA = objAs[1], ObjectB = objBs[0] });
                        tran.Commit();
                    }

                IList<LinkDAO> links = session.QueryOver<LinkDAO>().List();

                links.All(lk => { Console.WriteLine("{0} {1}", lk.ObjectA.Name, lk.ObjectB.Name); return true; });

                var ids = session.QueryOver<LinkDAO>().Select(x => x.ObjectA.Id, x => x.ObjectB.Id ).List<object[]>();

                ids.All(ary => { Console.WriteLine("{0} {1}", ary[0], ary[1]); return true; });
                }
            }
        }
    }
}

在测试运行结束时,您将看到:

NHibernate: SELECT this_.id_ObjectA as id1_2_0_, this_.id_ObjectB as id2_2_0_ FROM LinkTable this_
A1 B2
A2 B1
NHibernate: SELECT this_.id_ObjectA as y0_, this_.id_ObjectB as y1_ FROM LinkTable this_
1 2
2 1
于 2013-02-20T20:21:08.607 回答