当实体键的类型为bigint(ulong)时,如何将外键设置为null?

时间:2016-07-13 15:26:35

标签: codefluent

在我的模型中,我使用bigint(ulong)作为实体键的类型。我希望数据库强制引用完整性,因此我将persistenceEnforce设置为true。外键的列可以为空。使用引用完整性,只有在没有外键引用该实体时才能删除实体,因此在删除实体之前,我必须首先将该关联实体的每个外键设置为null。但是,我不知道如何清除外键。

这是我的模特:

<cf:entity name="Order" cfom:bindingList="false">
  <cf:property name="Id" typeName="ulong" key="true" persistenceIdentity="true" cfps:hint="CLUSTERED" />
  <cf:property name="Invoice" typeName="Invoice" persistenceEnforce="true" />
</cf:entity>

<cf:entity name="Invoice" cfom:bindingList="false">
  <cf:property name="Id" typeName="ulong" key="true" persistenceIdentity="true" cfps:hint="CLUSTERED" />    
  <cf:property name="Name" typeName="string" />
</cf:entity>

这是我的代码:

Invoice invoice = new Invoice();
invoice.Save();

Order order = new Order();
order.Invoice = invoice;
order.Save();

// We must clear the reference to the invoice before deleting the invoice,
// because the database enforces referential integrity.
order.InvoiceId = 0;
order.Save();

invoice.Delete();

以上代码在第二次保存订单时抛出以下异常: UPDATE语句与FOREIGN KEY约束冲突\&#34; FK_Ord_Ore_Inv_Inv \&#34;。

这是因为CodeFluent生成的代码将值0而不是null插入&#34; Order_Invoice_Id&#34;柱。 Order.BaseSave方法中的以下行似乎是错误的:     persistence.AddParameter(&#34; @ Order_Invoice_Id&#34;,this.InvoiceId,((ulong)(0ul)));

我尝试了设置persistenceDefaultValue =&#34; null&#34;和usePersistenceDefaultValue =&#34; true&#34;在Invoice propery上,但这并没有解决问题。

1 个答案:

答案 0 :(得分:0)

注意:类型为UInt64(无符号)的属性将转换为bigint类型的列(已签名)。因此,请注意转换... FYI CodeFluent实体使用CodeFluent.Runtime.Utilities.ConvertUtilities转换值。

重载AddParameter(string name, ulong value, ulong defaultValue)没有使用默认值,因此它不会将默认值转换为NULL。作为一种变通方法,您可以创建一个PersistenceHook来更改参数的值以匹配预期的行为:

public class CustomPersistenceHook : BasePersistenceHook
{
    public override void AfterAddParameter(string name, object value, IDbDataParameter parameter)
    {
        if (value is ulong && name == "@Order_Invoice_Id")
        {
            var defaultValue = (ulong)ContextData["defaultValue"];
            if (defaultValue == (ulong)value)
            {
                parameter.Value = DBNull.Value;
            }
        }

        base.AfterAddParameter(name, value, parameter);
    }
}

然后,您需要注册持久性挂钩:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <configSections>
    <section name="Sample" type="CodeFluent.Runtime.CodeFluentConfigurationSectionHandler, CodeFluent.Runtime" />
  </configSections>

  <Sample persistenceHookTypeName="Sample.CustomPersistenceHook, Sample" />
</configuration>