使用nhibernate将外键更新为Null值

时间:2011-01-31 10:46:19

标签: asp.net nhibernate

我有两个表BuildGroup和表DocumentTemplate。 DocumentTemplate表将BuildGroupId作为可以为空的外键。在某个senario中,我更新了DocumentTemplate表中的BuildGroupId。

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;
        }

    }

在另一个Senario中,我需要再次在DocumentTemplate表中设置BuildGroupId dbnull.value。我尝试了不同的情况,如在else块中。它给出了错误:不能 隐式转换类型'System.DBNull'为'int'。 如何使用NULL更新外键值?任何帮助将不胜感激。

2 个答案:

答案 0 :(得分:2)

一些观察结果:

  • 您不应将Id分配给HSBuildGroup对象,而是在bldGrpId不为0的情况下通过Session.Load()加载实例。
  • 您可以将文档的构建组设置为null,如下所示:

    objDocBO.HSBuildGroup = null;

    NHibernate将负责其余部分。

希望有所帮助。

答案 1 :(得分:1)

使用Session.Load和null作为Kay Herzam说。

您必须确保文件存在才能调用session.Load。例如:

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会执行像

这样的东西
select ... from DocumentTemplate where DocId = ..;
UPDATE DocumentTemplate SET .... , BuildGroupId = null where DocumentId = XX;

select ... from DocumentTemplate where DocId = ..;
UPDATE DocumentTemplate SET .... , BuildGroupId = YY where DocumentId = XX;

注意没有为数据库选择BuildGroup。

如果您不确定构建组是否存在,则代码应如下所示:

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会执行像

这样的东西
select ... from DocumentTemplate where DocId = ..;
SELECT .... FROM BuildGroup where buildgroupid = ZZ;
UPDATE DocumentTemplate SET .... , BuildGroupId = null where DocumentId = XX;

如果对象不存在,则获取自动返回null。

最后,您不需要调用Session.Update(),这是为了重新附加实体。提交事务时,将刷新与会话关联的所有内容。