简体   繁体   English

nhibernate连接表和自定义类型

[英]nhibernate joining tables and custom type

I'm new to Nhibernate. 我是Nhibernate的新手。 When I try to run the program i built I get this error. 当我尝试运行我构建的程序时,出现此错误。 "Unable to cast object of type 'Post_OfficeProxy' to type 'System.String'." “无法将类型为'Post_OfficeProxy'的对象强制转换为类型'System.String'。”

The DB tables are 数据库表是

POSTOFFICE.POST_OFFICE (PO_CODE char(8), PO_NAME, PO_ADD) POSTOFFICE.POST_OFFICE (PO_CODE字符(8),PO_NAME,PO_ADD)

POSTOFFICE.RECEIPT_BOOK (BOOK_NO, PO_CODE char(7), ADD_DATE, ADD_USER, ADD_IP_ADDRESS) POSTOFFICE.RECEIPT_BOOK (BOOK_NO,PO_CODE char(7),ADD_DATE,ADD_USER,ADD_IP_ADDRESS)

PO_CODE column contain the same data, but foreign key is not defined The result I want is a grid containing BOOK_NO, PO_CODE, PO_NAME, ADD_DATE, ADD_USER, ADD_IP_ADDRESS when PO_CODE is given. PO_CODE列包含相同的数据,但未定义外键。给定PO_CODE时,我想要的结果是一个包含BOOK_NO,PO_CODE,PO_NAME,ADD_DATE,ADD_USER,ADD_IP_ADDRESS的网格。

Post_Office.hbm.xml file Post_Office.hbm.xml文件

<?xml version="1.0" encoding="utf-8" ?><hibernate-mapping  xmlns="urn:nhibernate-mapping-2.2" assembly="Postal"  namespace="Postal.Models">  <class name="Post_Office" table="POSTOFFICE.POST_OFFICE" lazy="true" >
<id name="PO_CODE" column="PO_CODE" />
<property name="PO_NAME">
  <column name="PO_NAME" sql-type="VARCHAR2" not-null="true" />
</property>
<property name="PO_ADD">
  <column name="PO_ADD" sql-type="VARCHAR2" not-null="false" />    </property>  </class></hibernate-mapping>

Reciept.hbm.xml file Reciept.hbm.xml文件

    <?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping  xmlns="urn:nhibernate-mapping-2.2" assembly="Postal"  namespace="Postal.Models">
  <class name="Reciept" table="POSTOFFICE.RECEIPT_BOOK" lazy="true" >

    <id name="Book_no" column="BOOK_NO" />

    <many-to-one name="po_code" class="Post_Office" column="PO_CODE"  cascade="none" />
    <property name="Add_date">
      <column name="ADD_DATE" sql-type="DATE" not-null="false" />
    </property>

    <property name="Add_user">
      <column name="ADD_USER" sql-type="VARCHAR2" not-null="false" />
    </property>

    <property name="Add_ip_address">
      <column name="ADD_IP_ADDRESS" sql-type="VARCHAR2" not-null="false" />
    </property>


  </class>
</hibernate-mapping>

The two classes 两个班

using System.Linq;
using System.Web;
namespace Postal.Models
{
    public class Post_Office
    {
        [Key]
        [Required]
        [Display(Name = "PO code : ")]
        public virtual string PO_CODE { get; set; }

        [Required]
        [Display(Name = "PO Name : ")]
        public virtual string PO_NAME { get; set; }

        [Display(Name = "PO Address : ")]
        public virtual string PO_ADD { get; set; }
  }
}


public class Reciept
    {


        [Key]
        [Required]
        [Display(Name = "Book No. : ")]
        public virtual string Book_no { get; set; }

        [Required]
        [Display(Name = "PO code : ")]
        public virtual string po_code { get; set; }
    [Display(Name = "Add Date : ")]
    public virtual DateTime? Add_date { get; set; }

    [Display(Name = "Add User. : ")]
    public virtual string Add_user { get; set; }

    [Display(Name = "IP Address : ")]
    public virtual string Add_ip_address { get; set; }
}

The Function in the DAL Class DAL类中的功能

public IList<Reciept> Get_Records(string po_code)
        {
            IList<Reciept> p = null;
            using (ISession session = OpenSession())
            {
                Reciept d = null;
                Post_Office dt = null;

                try
                {
                    p = session.QueryOver<Reciept>(() => d)
                        .JoinAlias(() => d.po_code, () => dt)
                        //.Where(() => dt.PO_CODE == "PD06003")
                        .List<Reciept>();
                }
                catch (Exception rd)
                { }

            }
            return p;
        }

Can someone guide me in the right direction. 有人可以指引我正确的方向。 Thanks in advance 提前致谢

p = session.QueryOver<Reciept>(() => d)
                    .JoinAlias(() => d.po_code, () => dt)
                    //.Where(() => dt.PO_CODE == "PD06003")
                    .List<Reciept>();

In your JoinAlias, you are projecting d.po_code, which is a string, to the alias dt, which is an object of type Post_Office. 在JoinAlias中,将d.po_code(它是一个字符串)投影到别名dt(它是Post_Office类型的对象)上。 Receipt should not reference the key, but instead reference the Post_Office object. 收据不应引用密钥,而应引用Post_Office对象。

Change 更改

public virtual string po_code { get; set; }

to

public virtual Post_Office po { get; set; }

And this should work fine. 这应该很好。

p = session.QueryOver<Reciept>(() => d)
                .JoinAlias(() => d.po, () => dt)
                .Where(() => dt.PO_CODE == "PD06003")
                .List<Reciept>();

Update your mapping to reflect the variable name update also. 更新您的映射以反映变量名的更新。

Here's the final solution i came up with, thanks to Paul Connolly. 感谢Paul Connolly,这是我想出的最终解决方案。 For benefit of someone else I'll post it. 为了他人的利益,我将其发布。

Post_Office.hbm.xml Post_Office.hbm.xml

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping  xmlns="urn:nhibernate-mapping-2.2" assembly="Postal"  namespace="Postal.Models">
  <class name="Post_Office" table="POSTOFFICE.POST_OFFICE" lazy="true" >

    <id name="PO_CODE" column="PO_CODE" type="Postal.MyChar, Postal" />

    <property name="PO_NAME" type="">
      <column name="PO_NAME" sql-type="VARCHAR2" not-null="true" />
    </property>

    <property name="PO_TYPE">
      <column name="PO_TYPE" sql-type="VARCHAR2" not-null="false" />
    </property>

    <property name="PO_ADD1">
      <column name="PO_ADD1" sql-type="VARCHAR2" not-null="false" />
    </property>
  </class>
</hibernate-mapping>

Reciept.hbm.xml Reciept.hbm.xml

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping  xmlns="urn:nhibernate-mapping-2.2" assembly="Postal"  namespace="Postal.Models">
  <class name="Reciept" table="POSTOFFICE.RECEIPT_BOOK" lazy="true" >

    <id name="Book_no" column="BOOK_NO" />

    <many-to-one name="po" class="Post_Office" column="PO_CODE"  cascade="none" />


    <property name="Add_date">
      <column name="ADD_DATE" sql-type="DATE" not-null="false" />
    </property>

    <property name="Add_user">
      <column name="ADD_USER" sql-type="VARCHAR2" not-null="false" />
    </property>

    <property name="Add_ip_address">
      <column name="ADD_IP_ADDRESS" sql-type="VARCHAR2" not-null="false" />
    </property>


  </class>
</hibernate-mapping>

Post_Office class 邮局类

using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Web;

namespace Postal.Models
{
    public class Post_Office
    {
        [Key]
        [Required]
        [Display(Name = "PO code : ")]
        public virtual string PO_CODE { get; set; }

        [Required]
        [Display(Name = "PO Name : ")]
        public virtual string PO_NAME { get; set; }

        [Display(Name = "PO_TYPE : ")]
        public virtual string PO_TYPE { get; set; }

        [Display(Name = "PO_ADD1 : ")]
        public virtual string PO_ADD1 { get; set; }

    }
}

Reciept class 接收班

using System.ComponentModel.DataAnnotations;
using System.Linq;
using System.Web;

namespace Postal.Models
{
    public class Reciept
    {
        [Key]
        [Required]
        [Display(Name = "Book No. : ")]
        public virtual string Book_no { get; set; }

        [Required]
        [Display(Name = "PO code : ")]
        //public virtual string po_code { get; set; }

        public virtual Post_Office po { get; set; }

        [Display(Name = "Add Date : ")]
        public virtual DateTime? Add_date { get; set; }

        [Display(Name = "Add User. : ")]
        public virtual string Add_user { get; set; }

        [Display(Name = "IP Address : ")]
        public virtual string Add_ip_address { get; set; }
    }
}

I needed a custom type, as the columns i was joining with had two lengths(char(8) and Char(7)) MyChar class 我需要一个自定义类型,因为我要加入的列有两个长度(char(8)和Char(7))MyChar类

using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Web;
using NHibernate;
using NHibernate.SqlTypes;
using NHibernate.UserTypes;

namespace Postal
{
    public class MyChar:IUserType
    {

        public bool IsMutable
        {
            get { return false; }
        }
        public Type ReturnedType
        {
            get { return typeof(string); }
        }

        public SqlType[] SqlTypes
        {
            get { return new SqlType[1] { new SqlType(DbType.AnsiStringFixedLength) }; }
        }

        public object Assemble(object cached, object owner)
        {
            return this.DeepCopy(cached);
        }

        public object DeepCopy(object value)
        {
            if (value == null)
            {
                return (object)null;
            }
            else
            {
                return (object)string.Copy((string)value);
            }
        }

        public object Disassemble(object value)
        {
            return this.DeepCopy(value);
        }

        public bool Equals(object x, object y)
        {
            if (x == null)
            {
                return y == null;
            }
            else
            {
                return x.Equals(y);
            }
        }

        public int GetHashCode(object x)
        {
            return x.GetHashCode();
        }

        public object NullSafeGet(IDataReader rs, string[] names, object owner)
        {
            string str = (string)NHibernateUtil.String.NullSafeGet(rs, names[0]);
            return str != null ? (object)str.Trim() : (object)(string)null;
        }

        public void NullSafeSet(IDbCommand cmd, object value, int index)
        {
            if (value == null)
            {
                NHibernateUtil.String.NullSafeSet(cmd, (object)null, index);
            }
            else
            {
                value = (object)((string)value).Trim();
                NHibernateUtil.String.NullSafeSet(cmd, value, index);
            }
        }

        public object Replace(object original, object target, object owner)
        {
            return original;
        }
    }
}

Method in my DAL class 我的DAL类中的方法

public IList<Reciept> Get_Terrorist_Records2(string po_code)
        {
            IList<Reciept> p = null;
            using (ISession session = OpenSession())
            {
                Reciept d = null;
                Post_Office dt = null;

                try
                {
                    p = session.QueryOver<Reciept>(() => d)
                    .JoinAlias(() => d.po, () => dt)
                    .Where(() => dt.PO_CODE == po_code)
                    .List<Reciept>();


                }
                catch (Exception rd)
                { }

            }
            return p;
        }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM