2016-07-05 42 views
0

在我的模型中,我使用bigint(ulong)作爲實體鍵的類型。 0值必須用於空鍵。 外鍵的列不能爲空,因爲在我的方法中,我只想檢查值0而不是null。 一切工作正常,除了刪除其他實體引用的相關實體。當刪除相關實體時,CodeFluent嘗試更新一個類型爲bigint的不可爲空的外鍵

這裏是我的模型:

<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 [訂購] SET [訂購] [Order_Customer_Id] = NULL WHERE([訂購] [Order_Customer_Id] = @Customer_Id。)

當然,這是行不通的,因爲Order_Customer_Id列是不可空的。 如何指示CodeFluent將值0而不是NULL置於Order_Customer_Id列中?

回答

1

CodeFluent並不真正支持不可空的對象鍵,因爲隱含的語義會有點奇怪。從OO的角度來看,當你刪除一個對象時,該對象現在是空的,它的標識符不再存在,它沒有被設置爲特定的0或其他值。您可能會遇到其他問題,像這樣調整模型。

也就是說,改變這種行爲的一種方法是直接在XML文件中使用涉及屬性的「persistenceUnlink」屬性。不幸的是,圖形建模器不支持這個(古老的)屬性,並且每次修改模型並使用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文件(它應該顯示方面元數據),然後按確定。
  • 返回到圖形建模器的設計界面,單擊要刪除持久性鏈接的屬性,轉到Visual Studio屬性網格,選擇藍色的「方面和生產者屬性」選項卡,然後將「取消鏈接」設置爲現在應顯示的錯誤(默認爲true)。
  • 重建,並且存儲過程代碼不應再包含此關係的鏈接。
相關問題