0

私のモデルでは、エンティティ キーの型として bigint (ulong) を使用しています。データベースで参照整合性を強制したいので、persistenceEnforce を true に設定しました。外部キーの列は null 可能です。参照整合性を使用すると、外部キーがエンティティを参照していない場合にのみエンティティを削除できるため、エンティティを削除する前に、まずこの関連付けられたエンティティの各外部キーを 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();

上記のコードは、注文を 2 回目に保存するときに次の例外をスローします。UPDATE ステートメントが FOREIGN KEY 制約 \"FK_Ord_Ore_Inv_Inv\" と競合しました。

これは、CodeFluent によって生成されたコードが null の代わりに値 0 を「Order_Invoice_Id」列に挿入するためです。Order.BaseSave メソッドの次の行が間違っているようです: persistence.AddParameter("@Order_Invoice_Id", this.InvoiceId, ((ulong)(0ul)));

Invoice プロパティで persistenceDefaultValue="null" と usePersistenceDefaultValue="true" の設定を試みましたが、問題は解決しませんでした。

4

1 に答える 1

0

注: タイプUInt64(unsigned) のプロパティは、タイプbigint(signed) の列に変換されます。したがって、変換には注意してください... 参考までに、CodeFluent Entities はCodeFluent.Runtime.Utilities.ConvertUtilities値の変換に使用します。

オーバーロードAddParameter(string name, ulong value, ulong defaultValue)はデフォルト値を使用しないため、デフォルト値を に変換しませんNULLPersistenceHook回避策として、期待される動作に一致するようにパラメーターの値を変更するを作成できます。

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 に答える