0

私のモデルでは、エンティティ キーの型として bigint (ulong) を使用しています。空のキーには値 0 を使用する必要があります。私のメソッドでは値 0 のみをチェックし、null をチェックしたくないため、外部キーの列は null 可能であってはなりません。他のエンティティによって参照されている関連エンティティの削除を除いて、すべて正常に機能します。

これが私のモデルです:

<cf:entity name="Customer" cfom:bindingList="false">
  <!--persistenceIdentity is true, because the corresponding column for this property must be auto incremented by the database.-->
  <cf:property name="Id" typeName="ulong" key="true" persistenceIdentity="true" cfps:hint="CLUSTERED" />
  <cf:property name="Name" typeName="string" />
</cf:entity>

<cf:entity name="Order" cfom:bindingList="false">
  <!--persistenceIdentity is true, because the corresponding column for this property must be auto incremented by the database.-->
  <cf:property name="Id" typeName="ulong" key="true" persistenceIdentity="true" cfps:hint="CLUSTERED" />

  <!--persistenceNullable is false, because the column for the foreign key must not be nullable.-->
  <cf:property name="Customer" typeName="{0}.Customer" persistenceNullable="false" />
</cf:entity>

これが私のコードです:

Customer customer = new Customer();
customer.Save();
Order order = new Order();
order.Customer = customer;
order.Save();
customer.Delete();

最後のステートメントは次のエラーを返します。値 NULL を列 'Order_Customer_Id'、テーブル 'CodeFluentTest.dbo.Order' に挿入できません。列はヌルを許可しません。更新は失敗します。

これは、Customer_Delete ストアド プロシージャに次の更新ステートメントが含まれているためです。UPDATE [Order] SET [Order].[Order_Customer_Id] = NULL WHERE ([Order].[Order_Customer_Id] = @Customer_Id)

もちろん、Order_Customer_Id 列は NULL 可能ではないため、これは機能しません。Order_Customer_Id 列に NULL の代わりに値 0 を入れるように CodeFluent に指示するにはどうすればよいですか?

4

1 に答える 1

1

CodeFluent は、null 許容でないオブジェクト キーを実際にはサポートしていません。オブジェクトを削除すると、OO の観点から、オブジェクトは null になり、識別子は存在しなくなり、特定の 0 またはその他の値に設定されません。このようにモデルを微調整すると、おそらく他の問題に遭遇するでしょう。

そうは言っても、この動作を変更する 1 つの方法は、persistenceUnlink関連するプロパティの " " 属性を XML ファイルで直接使用することです。残念ながら、グラフィカル モデラーはこの (古い) 属性をサポートしておらず、モデルを変更して GUI を使用して保存するたびに上書きされます。

したがって、カスタム アスペクトを使用して、この属性を必要なプロパティに自動的に適用することができます。このようなアスペクトのサンプル コードを次に示します (アスペクトは起動時に実行されることに注意してください。これは、ほとんどのアスペクトとは異なり、メモリ内モデルではなく XML に実際に基づいているためです)。

<cf:project xmlns:cf="http://www.softfluent.com/codefluent/2005/1" defaultNamespace="unlink">
  <cf:pattern name="Unlink Aspect" namespaceUri="http://www.example.com/unlink" preferredPrefix="ul" step="Start">
    <cf:message class="_doc">
       Sample aspect that removes auto unlink in delete procedures
    </cf:message>
    <cf:descriptor name="unlink" targets="Property" defaultValue="true" displayName="Unlink" typeName="boolean" description="Determines if this property will be unlinked during delete" category="Unlink Aspect" />
  </cf:pattern>

  <?code @namespace name="System" ?>
  <?code @namespace name="System.Xml" ?>
  <?code @namespace name="CodeFluent.Model" ?>

<?code
      // use a special utility method to get all elements
      // with the given attribute in a given namespace URI
      var properties  = Project.Package.RootModelPart.SelectElements("unlink", "http://www.example.com/unlink", false);
      foreach(var property in properties)
      {
        // here we set a special attribute not supported by the GUI designer in Visual Studio
        property.SetAttribute("persistenceUnlink", "false");
      }

?>
</cf:project>

あなたがしなければならないことは次のとおりです。

  • このコードをファイルとして保存します。たとえば、「unlink.xml」をプロジェクト ファイルのどこかに保存します。
  • グラフィカル モデラーで、CodeFluent プロジェクトの [アスペクト] ノードを右クリックし、[既存のアスペクトを追加] を選択し、unlink.xml ファイルを参照して (アスペクト メタデータが表示されるはずです)、[OK] を押します。
  • グラフィカル モデラーのデザイン サーフェイスに戻り、永続化リンクを削除するプロパティをクリックし、Visual Studio プロパティ グリッドに移動して、青色の [アスペクトとプロデューサー プロパティ] タブを選択し、[リンク解除] を False に設定します。表示されるようになりました (デフォルトは true)。
  • 再構築し、ストアド プロシージャ コードにこの関係へのリンクが含まれないようにする必要があります。
于 2016-07-05T22:26:16.723 に答える