Updating a foreign key to Null value using nhibernate
我有两个表 BuildGroup 和表 DocumentTemplate。 DocumentTemplate 表具有 BuildGroupId 作为可以为空的外键。在某个场景中,我更新了 DocumentTemplate 表中的 BuildGroupId。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | public bool EditDocTempForBldGrp(int docId, int bldGrpId) { try { using (ISession session = Document.OpenSession()) { using (ITransaction transaction = session.BeginTransaction()) { HSDocumentTemplate objDocBO = new HSDocumentTemplate(); objDocBO = GetDocumentDetailsById(docId); HSBuildGroup objBldGrp = new HSBuildGroup(); if (bldGrpId != 0) { objBldGrp.Id = bldGrpId; } else { //int ? bldid = null; //objDocBO.HSBuildGroup.Id = null; //objDocBO.HSBuildGroup.Id = DBNull.Value; //objDocBO.HSBuildGroup.Id = -1; } objDocBO.HSBuildGroup = objBldGrp; session.Update(objDocBO); transaction.Commit(); } } return true; } catch (Exception ex) { Console.WriteLine(ex.Message); return false; } } |
在另一个场景中,我需要再次将 DocumentTemplate 表中的 BuildGroupId 设置为
dbnull.value。我尝试了不同的情况,如在 else 块中。它给出了错误:不能
将类型 \\'System.DBNull\\' 隐式转换为 \\'int\\'。
如何使用 NULL 更新外键值?任何帮助将不胜感激。
一些观察:
- 您不应将 Id 分配给 HSBuildGroup 对象,而应通过 Session.Load() 加载实例,以防 bldGrpId 不为 0。
-
您可以像这样将文档的构建组设置为空:
objDocBO.HSBuildGroup = null;
NHibernate 会处理剩下的事情。
希望对您有所帮助。
正如 Kay Herzam 所说,使用 Session.Load 和 null。
您必须确定文件存在才能调用 session.Load。示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 | public bool EditDocTempForBldGrp(int docId, int bldGrpId) { try { using (ISession session = Document.OpenSession()) using (ITransaction transaction = session.BeginTransaction()) { session.Get<HSDocumentTemplate>(docId).HSBuildGroup = bldGrpId = 0 ? null : session.Load<HSBuildGroup>(bldGrpId); transaction.Commit(); } } } |
这样,nhibernate 会执行类似的操作,
1 2 | select ... from DocumentTemplate where DocId = ..; UPDATE DocumentTemplate SET .... , BuildGroupId = null where DocumentId = XX; |
或
1 2 | select ... from DocumentTemplate where DocId = ..; UPDATE DocumentTemplate SET .... , BuildGroupId = YY where DocumentId = XX; |
请注意,没有选择 BuildGroup 到数据库。
如果您不确定构建组的存在,您的代码应如下所示:
1 2 3 4 5 6 7 8 9 10 11 12 13 | public bool EditDocTempForBldGrp(int docId, int bldGrpId) { try { using (ISession session = Document.OpenSession()) using (ITransaction transaction = session.BeginTransaction()) { session.Get<HSDocumentTemplate>(docId).HSBuildGroup = session.Get<HSBuildGroup>(bldGrpId); transaction.Commit(); } } } |
这样,nhibernate 会执行类似的操作,
1 2 3 | select ... from DocumentTemplate where DocId = ..; SELECT .... FROM BuildGroup where buildgroupid = ZZ; UPDATE DocumentTemplate SET .... , BuildGroupId = null where DocumentId = XX; |
如果对象不存在,Get 会自动返回 null。
最后你不需要调用 Session.Update() 这是为了重新附加一个实体。提交事务时,与 Session 关联的所有内容都将被刷新。