2016-07-05 3 views
0

私のモデルでは、エンティティキーの型としてbigint(ulong)を使用しています。 空のキーには値0を使用する必要があります。 私のメソッドでは値0をチェックしたいだけなので、外部キーのカラムはnullにできません。 他のエンティティによって参照される関連エンティティの削除を除いて、すべて正常に動作します。ここでCodeFluentは、関連するエンティティを削除するときに、nullint型の外部キーを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 ';列はNULLを許可しません。 UPDATEに失敗します。

Customer_Deleteストアドプロシージャは、次の更新ステートメントが含まれているためである:。 UPDATE [オーダー] SET [順序] [Order_Customer_Id] = NULL([オーダー] [Order_Customer_Id] = @Customer_Id。)

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

答えて

1

CodeFluentは、暗黙のセマンティクスが何らかの形で変わってしまうため、実際にはヌル可能ではないオブジェクトキーをサポートしていません。オブジェクトをOOパースペクティブから削除すると、オブジェクトはnullになり、識別子はもはや存在せず、特定の0または他の値に設定されません。このようなモデルを調整することで、おそらく他の問題にぶつかるでしょう。

この動作を変更する方法の1つは、関係するプロパティの "persistenceUnlink"属性をXMLファイルで直接使用することです。残念ながら、グラフィカル・モデラーはこの(古代の)属性をサポートしておらず、モデルを変更してGUIを使用してそれを元に戻すたびにオーバーライドします。

したがって、custom aspectを使用して、この属性を必要な場所に自動的に適用することができます。ここでは、そのような側面のためのサンプルコードは、(それが実際に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プロジェクトの「Aspects」ノードを右クリックし、「既存のアスペクトを追加」を選択し、unlink.xmlファイルをブラウズして(アスペクトのメタデータが表示されるはずです)、okを押します。
  • グラフィカルモデラーのデザイン画面に戻り、永続リンクを削除するプロパティをクリックし、Visual Studioのプロパティグリッドに移動して、青色の "アスペクトとプロデューサのプロパティ"タブを選択し、 "リンク解除"を現在表示されるはずのFalse(デフォルトはtrue)。
  • rebuildであり、ストアドプロシージャコードにはこの関係のリンクが含まれてはなりません。
関連する問題