代码之家  ›  专栏  ›  技术社区  ›  Amith George

nhibernate.typeMismatchException:提供了错误类型的ID。应为:System.Int32,获得System.Int64

  •  3
  • Amith George  · 技术社区  · 15 年前

    正在使用以下查询获取客户端。客户端具有long类型的公共ID。

    var client = Session.CreateQuery("from Client as c where c.Id = :Id").SetParameter("Id", 1, NHibernateUtil.Int64).UniqueResult<Client>();
    

    正在获取错误:

    nhibernate.typeMismatchException:提供了错误类型的ID。应为:System.Int32,获得System.Int64

    同时,以下工作也很好。

    var client = Session.Get<Client>(1L); //Or
    var client = Session.CreateCriteria<Client>().Add(Restrictions.Eq("Id", 1L)).UniqueResult<Client>();
    

    我错过了什么?正在使用Fluent NHibernate创建映射。我已经针对一个sqlite和一个mysql数据库测试了这些查询。同样的结果。

    编辑1 :从映射生成的模式显然在使用bigint作为mysql上的主键。这就是为什么我无法理解期望的Int32是什么?

    编辑2 :好的,我的客户机类引用了一个报表对象。它实际上是数据库中的一对一关系,报表表有一个列clientid。报表类具有int类型的ID。一旦我将其类型更改为long,错误就消失了。

    我的映射如下:

    客户地图:

    HasOne<Report>(x => x.Report)
       .PropertyRef(x => x.Client)
       .LazyLoad()
       .Cascade.SaveUpdate();
    

    ReportMap:

    References(x => x.Client, "clientID").Unique();
    

    所以,为什么这个问题通过将reportid的类型从int改为long来解决。第二,我不要求的时候,为什么还要去拿报告呢?

    1 回复  |  直到 15 年前
        1
  •  5
  •   tinonetic    8 年前

    一对一键需要具有相同的类型定义,因为它们使用相同的值。因此,ID=Int32.MaxValue+1的客户机将具有ID=Int32.MaxValue+1的对应报表,因此它们必须同时是 long .

    我推荐这些文章来理解一对一以及在大多数情况下你并不真正需要它: