为什么使用NHibernate将Id从1更改为1

为什么使用NHibernate将Id从1更改为1,nhibernate,Nhibernate,我有一个这样的映射 <class name="UserFileSummary" table="UserFile" lazy="false"> <id name="FileId" column="UserFileId" type="int"> <generator class="identity" /> </id>... public long FileId { get; set; } myFile.myProperty

我有一个这样的映射

<class name="UserFileSummary" table="UserFile" lazy="false">
   <id name="FileId" column="UserFileId" type="int">
      <generator class="identity" />
   </id>...
public long FileId { get; set; }
myFile.myProperty = newValue
session.Save(myFile)
我不明白的是,当我使用

var myFile = session.Get<UserFileSummary>(id)
我收到一个错误,说Id已从1更改为1。关于这一点有一些帖子,但这是一个简单的int列(标识1,1)。我一定犯了一些基本的错误,请任何人帮帮忙。谢谢

我添加了这一点作为编辑,因为这个问题原来是一个非问题

FileId属性的类型为long,映射的类型为int,这就是为什么从1更改为1是一个问题


如果你想让我删除这个问题,请给我一些反馈,谢谢大家:)

我能从你的代码中指出的唯一一点是使用
Save
更新现有实体

您可以避免显式调用会话中始终存在的实体的Save方法。刷新会话时,更改将自动保留


如果您坚持显式调用update方法,我会说您应该使用
SaveOrUpdate

从您的代码中,我唯一能指出的是使用
Save
更新现有实体

您可以避免显式调用会话中始终存在的实体的Save方法。刷新会话时,更改将自动保留


如果您坚持显式调用update方法,我建议您首先使用
SaveOrUpdate

,将属性上的setter设置为private;如果有错误设置项目的代码,项目将无法编译。无论如何,这是一个很好的做法。但这并不是万无一失的,因为类中可能存在设置它的代码,所以您必须对此进行检查

public int FileId { get; private set; }

其次,仔细检查映射文件,确保没有两次映射该字段。

首先,将属性上的setter设置为private;如果有错误设置项目的代码,项目将无法编译。无论如何,这是一个很好的做法。但这并不是万无一失的,因为类中可能存在设置它的代码,所以您必须对此进行检查

public int FileId { get; private set; }


其次,仔细检查映射文件,确保没有两次映射该字段。

在我的例子中,错误是由于数据库中的数据类型为long(int64),并且映射到映射中的int(int32)。这意味着无论何时保存对象,实际值都会更改,从而破坏标识符。感谢所有帮助过我的人。

我的案例中的错误是由于数据库中的数据类型是long(int64),并且在映射中被映射为int(int32)。这意味着无论何时保存对象,实际值都会更改,从而破坏标识符。感谢所有帮助过我的人。

你有完整的类映射来演示这个问题吗?我可以编一些映射,但我希望避免大量的代码发布,以使问题尽可能有用。这个类的其他部分没有什么奇怪的地方,只有字符串和int字段。我只是想要一些简短的东西,我可以运行,我还想知道是否有一个属性映射到Id,这会让nhibernate感到困惑。谢谢,抱歉听起来是否定的。有一个属性映射到Id。我注意到claudio建议保存或更新,我已经尝试过了,但我会再看一看。我通过存储库模式使用会话,所以说我使用的是session.save有点像合成。再次感谢:)完整的错误消息是什么?您有完整的类映射来演示问题吗?我可以编一些映射,但我希望避免大量的代码发布,以使问题尽可能有用。这个类的其他部分没有什么奇怪的地方,只有字符串和int字段。我只是想要一些简短的东西,我可以运行,我还想知道是否有一个属性映射到Id,这会让nhibernate感到困惑。谢谢,抱歉听起来是否定的。有一个属性映射到Id。我注意到claudio建议保存或更新,我已经尝试过了,但我会再看一看。我通过存储库模式使用会话,所以说我使用的是session.save有点像合成。再次感谢:)完整的错误消息是什么?谢谢,我使用的是存储库模式,所以我并不真正调用save。不确定这是什么原因造成的。:)当我删除私有setter时,我注意到id字段是一个长数据类型。显然,消息“从1改为1”在这种情况下是有意义的,这将是一个问题。现在,我把它全部设置为int,它使用我的存储库模式工作得很好。很抱歉浪费了您的时间:)没问题:)很高兴您终于找到了答案。谢谢,我使用的是存储库模式,所以我并不真正调用save。不确定这是什么原因造成的。:)当我删除私有setter时,我注意到id字段是一个长数据类型。显然,消息“从1改为1”在这种情况下是有意义的,这将是一个问题。现在,我把它全部设置为int,它使用我的存储库模式工作得很好。抱歉浪费您的时间:)没问题:)很高兴您终于找到了答案。这需要
保护
,NHibernate才能拿起它。不,它没有。NHibernate使用反射设置属性,以便可以访问私有setter。我所有使用标识键的对象都有私有setter。嗯,我试过了,但它会弄乱很多其他东西,而且我还有很多其他项目,其中Id是读写的,没有问题。当我删除私有setter时,我注意到Id字段是一个长数据类型。显然,消息“从1改为1”在这种情况下是有意义的,这将是一个问题。现在,我把它全部设置为int,它使用我的存储库模式工作得很好。很抱歉浪费您的时间:)在我看来,在使用数据库生成(标识)ID的NHibernate应用程序中,带有非私有setter的标识符是一个重要的设计