Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/video/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# NHibernate:没有使用复合密钥的更新_C#_Nhibernate_Fluent Nhibernate - Fatal编程技术网

C# NHibernate:没有使用复合密钥的更新

C# NHibernate:没有使用复合密钥的更新,c#,nhibernate,fluent-nhibernate,C#,Nhibernate,Fluent Nhibernate,我有一个使用Nhibernate保存的对象。此对象使用复合键,声明如下: CompositeId() .KeyProperty(x => x.CreditorName) .KeyProperty(x => x.CreditorIBAN) .KeyReference(x => x.Config, "ProfileName"); Map(x => x.ID, "ID").ReadOnl

我有一个使用Nhibernate保存的对象。此对象使用复合键,声明如下:

        CompositeId()
          .KeyProperty(x => x.CreditorName)
          .KeyProperty(x => x.CreditorIBAN)
          .KeyReference(x => x.Config, "ProfileName");
        Map(x => x.ID, "ID").ReadOnly();
        Map(x => x.CreationDate, "CreationDate").Default(null);
        Map(x => x.ContractReference, "ContractReference");
        Map(x => x.CreditorBIC, "CreditorBIC");

        References<C_ContractType>(x => x.ContractType, "ContractType_ID");
        References<C_Country>(x => x.CreditorCountry, "CreditorCountry"); 

        Table("Creditor");
        Cache.ReadWrite();
CompositeId()
.KeyProperty(x=>x.CreditorName)
.KeyProperty(x=>x.CreditorIBAN)
.KeyReference(x=>x.Config,“ProfileName”);
Map(x=>x.ID,“ID”).ReadOnly();
Map(x=>x.CreationDate,“CreationDate”).Default(null);
地图(x=>x.ContractReference,“ContractReference”);
Map(x=>x.CreditorBIC,“CreditorBIC”);
参考文献(x=>x.ContractType,“ContractType_ID”);
参考文献(x=>x.CreditorCountry,“CreditorCountry”);
表(“债权人”);
Cache.ReadWrite();
我们可以毫无问题地保存,但当我们尝试使用
Session.SaveOrUpdate(entity)更新字段时(无论是哪一个字段)未执行任何操作(无更新)且没有错误消息

我们错过什么了吗?谢谢你的帮助

--编辑--


我在update方法之后添加了
Session.Flush()
,这样会更好一些,因为我可以更新任何值,除了键中的值(CreditorName和CreditorIBAN)。有什么想法吗?

在将更改写入数据库之前,您必须刷新或提交会话

再看看这个:


I.持久化,执行sql写入命令

正如在评论中所讨论的,我们需要做的第一件事就是使用ISession.Flush()扩展代码

(有人引用)


除了显式Flush()之外,对于会话何时执行ADO.NET调用,绝对没有任何保证,只有执行顺序

正如这里所讨论的

我们可以在会话创建期间指定默认刷新模式

var session = SessionFactory.OpenSession();
session.FlushMode = FlushMode.Commit;
并确保在事务提交后将调用它,或在需要时随时显式调用它

Session.SaveOrUpdate(entity);
Session.Flush();
II。键/Id更改用于已持久化的而非临时实体

这是有意为之,无意为之。因为DB
,所以C#运行时实体
Id
是指向实例的数据层指针。我们不应该处理这些问题,我们不应该试图去思考它们

我们的实体应仅通过参考进行管理:

var entity = ...;
entity.ContractType = someContractType;
entity.CreditorCountry = defaultCountry;
...
通过这种方式,我们分配db密钥,表示为ID。。。在一个Flush()上,没有提到它们

这也是为什么我们不应该考虑改变它们的能力

我们能做的最好的事情就是不使用复合键,而是使用

数据库中的代理项是建模世界中实体或数据库中对象的唯一标识符。代理项键不是从应用程序数据派生的,这与从应用程序数据派生的自然(或业务)键不同

使用SQL Server很容易引入标识为(1,1)的新列。。。只需使用ALTER TABLE TheID INT NOT NULL IDENTITY(1,1)
。。。就在那里

将所有复合零件重新映射到属性(
.map()
.References()
),然后可以更改任何需要的内容

我可以理解这不是理想的答案,但我强烈建议至少考虑一下。简单地说

密钥只能生成一次。然后永远保持不变。。。或与其行/实例一起删除


这里非常重要的一点是:“Session.SaveOrUpdate(entity)”不会持久化任何内容。它只是更改会话中的数据(如果以前已分离)。。。请确保您已经调用了Session.Flush()@RadimKöhler:谢谢。正如你可能已经看到的,我添加了这个,但它只是稍微好一点。还有其他想法吗?西奥斯,你很可能不会喜欢我的答案,但我认为这是我能分享的最好的建议。。希望能有点帮助…谢谢。我这样做了,它稍微好一点,因为我可以更新任何值,除了那些键(CreditorName和CreditorIBAN)。有什么想法吗?西格我就知道会变成这样。。。啊!我希望有一个更好的。。先生,祝您愉快!这是一个神奇的工具;)老实说,我不喜欢它。这在大多数情况下都很有帮助,但仅仅因为有5%的情况下,我更喜欢使用其他东西。这只是因为这个项目是一个旧的,我使用它。