如何在N层应用程序中使用Fluent NHibernate?

如何在N层应用程序中使用Fluent NHibernate?,nhibernate,fluent-nhibernate,n-tier-architecture,Nhibernate,Fluent Nhibernate,N Tier Architecture,我试图在我的项目中采用Fluent NHibernate,目前我可以从数据库中获取数据,当我在应用服务器上时,数据包括其PK,但当我将此数据(作为列表)返回到客户端时,其PK都是松散的 我如何解决这个问题 更新 我的POCO课程如下:PK是CountryCd和CityCd public class coCity { public virtual string CountryCd { get; private set; } public virtual string CityCd

我试图在我的项目中采用Fluent NHibernate,目前我可以从数据库中获取数据,当我在应用服务器上时,数据包括其PK,但当我将此数据(作为列表)返回到客户端时,其PK都是松散的

我如何解决这个问题

更新

我的POCO课程如下:PK是CountryCd和CityCd

public class coCity
{
    public virtual string CountryCd { get; private set; }
    public virtual string CityCd { get; private set; }
    public virtual string CityNameTH { get; set; }
    public virtual string CityNameEN { get; set; }
    public virtual int DeliveryLeadTime { get; set; }
    public virtual string CreateBy { get; set; }
    public virtual DateTime CreateDate { get; set; }
    public virtual string UpdateBy { get; set; }
    public virtual DateTime UpdateDate { get; set; }

    public override bool Equals(object obj)
    {
        return this.GetHashCode().Equals(obj.GetHashCode());
    }

    public override int GetHashCode()
    {
        return (this.CountryCd + this.CityCd).GetHashCode();
    }
}
映射类:

public class coCityMap : ClassMap<coCity>
{
    public coCityMap()
    {
        Table("coCity"); // this is optional

        CompositeId()
            .KeyProperty(x => x.CountryCd)
            .KeyProperty(x => x.CityCd);
        Map(x => x.CityNameTH);
        Map(x => x.CityNameEN);
        Map(x => x.DeliveryLeadTime);
        Map(x => x.CreateBy);
        Map(x => x.CreateDate);
        Map(x => x.UpdateBy);
        Map(x => x.UpdateDate);
    }
}
公共类coCityMap:ClassMap
{
公共coCityMap()
{
表(“coCity”);//这是可选的
复合ID()
.KeyProperty(x=>x.CountryCd)
.KeyProperty(x=>x.CityCd);
地图(x=>x.CityNameTH);
地图(x=>x.CityNameEN);
Map(x=>x.DeliveryLeadTime);
映射(x=>x.CreateBy);
映射(x=>x.CreateDate);
Map(x=>x.UpdateBy);
Map(x=>x.UpdateDate);
}
}
在应用服务器上获取数据的源代码

public List<coCity> GetTest()
{
    List<coCity> result = new List<coCity>();

    var sessionFactory = CreateSessionFactory();

    using (var session = sessionFactory.OpenSession())
    {
        result = (List<coCity>)session.CreateCriteria(typeof(coCity)).List<coCity>();
    }

    return result;
}
公共列表GetTest()
{
列表结果=新列表();
var sessionFactory=CreateSessionFactory();
使用(var session=sessionFactory.OpenSession())
{
结果=(List)session.CreateCriteria(typeof(coCity)).List();
}
返回结果;
}
当其仍在应用服务器上时,正确检索数据,如下图所示

然而,当这个数据传输回客户端时,它的所有PK都是松散的,如下所示。

首先,这不是Fluent NHibernate的问题,因此:

  • 序列化POCO时,必须在其上使用Serializable
  • (根据您的评论)NHibernate将从数据库检索到的对象的引用保存到缓存(一级缓存)。序列化此“托管”对象时,序列化的输出是非托管对象。Nhibernate不会仅仅因为您在新构造的对象中设置了值而检测到数据库中存在对象。您必须从数据库获取对象并更新其属性并调用update(),或者使用纯sql处理从客户端返回的对象(yikes!)

  • 请注意,这与这个问题无关:您的Equals()实现非常糟糕,因为它不考虑类型,只依赖于GetHashCode值。如果您的所有类都有这个实现,您可能会遇到麻烦。

    我认为问题在于PK属性上的私有setter。试着把它改成公共的

    无论哪种方式,都要用
    Serializable

    几点意见:

    • 使用nhibernate时的一般建议是避免复合ID。在您的模型上创建一个作为标识列的代理Id,并在其他地方强制CityCd和CountryCd的唯一性
    • 当通过客户端/服务器层传递数据时,考虑使用以避免一些常见的LaZyRealItAllientExtruts异常问题。
    如果您展示了一些代码(特别是您的nHib绑定)并阐明了“其所有PK都是松散的(sic)”的含义,那么就容易多了。主键值是否真的消失了,就像在中被重置为默认值一样,还是只是没有明显地显示它们是主键?在客户端和服务器之间序列化时它不会丢失?@Stefan,如果我将Serializable添加到实体类中,那么它的数据不会丢失,但我不知道这样做是否正确?无论如何,即使它的PKs也不会松动,但当我将这个实体发送回服务器时,它总是尝试插入而不是更新。