0

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

这是我的模型:

<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 约束 \"FK_Ord_Ore_Inv_Inv\" 冲突。

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

我在 Invoice 属性上尝试了设置 persistenceDefaultValue="null" 和 usePersistenceDefaultValue="true",但这并没有解决问题。

4

1 回答 1

0

注意:(UInt64无符号)类型的属性被转换为(有符号)类型的列bigint。所以要小心转换... FYI CodeFluent Entities 用于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>
于 2016-07-13T15:54:06.743 回答