2015-10-19 61 views
3

我的模型包含以下枚舉和實體:如何加載PersistentList類型的屬性包含數組參數中的一個或多個值的實體?

<cf:enumeration name="Language" usePersistenceDefaultValue="false"> 
    <cf:enumerationValue name="EN" value="1" default="true" /> 
    <cf:enumerationValue name="NL" value="2" /> 
    <cf:enumerationValue name="DE" value="3" /> 
</cf:enumeration> 

<cf:entity name="Person" > 
    <cf:property name="Id" key="true" /> 

    <cf:property name="Languages" typeName="CodeFluent.Runtime.Utilities.PersistentList&lt;Language&gt;"> 
    <cf:message class="_doc">The languages that the person speaks</cf:message> 
    </cf:property> 

    <cf:method name="LoadPersonThatSpeaksOneOrMoreLanguages" checkLevel="None" memberAttributes="Public" > 
    <cf:body language="tsql" text="load(Language[] languages) from Person where Languages in (@languages)" /> 
    </cf:method> 
</cf:entity> 

的方法LoadPersonThatSpeaksOneOrMoreLanguages應該返回講所提供的語言的一個或多個的所有人員。 這種方法生成的存儲過程似乎並沒有被正確的:

ALTER PROCEDURE [dbo].[Person_LoadPersonThatSpeaksOneOrMoreLanguages] 
(

@languages [dbo].[cf_type_Person_LoadPersonThatSpeaksOneOrMoreLanguages_0] READONLY, 
@_orderBy0 [nvarchar] (64) = NULL, 
@_orderByDirection0 [bit] = 0 
) 
AS 
SET NOCOUNT ON 
DECLARE @_c_languages int; SELECT @_c_languages= COUNT(*) FROM @languages 
SELECT DISTINCT [Person].[Person_Id], ... 
    FROM [Person] 
    WHERE [Person].[Person_Languages] IN (((SELECT * FROM @languages))) 

問題1: 我怎樣才能達到預期的效果? 我應該創建一個語言實體並指定Person和Language之間的1:n關聯嗎?我更喜歡沒有語言實體。 或者我可以指定Languages屬性必須轉換爲與表值參數(cf_type_Person_LoadPersonThatSpeaksOneOrMoreLanguages_0)相同的類型嗎?

問題2: 生成的PersonCollection類包含方法LoadPersonThatSpeaksOneOrMoreLanguages。該方法的參數類型爲Language[]。我想要一個IEnumerable<Language>而不是一個數組。我怎樣才能在我的XML模型中指定這個?

回答

1

就像我正在研究的一個話題一樣,但從來沒有實施過的話,我會說一點鹽。隨着中說另一種方法是使用一個多值枚舉(標誌)

http://blog.codefluententities.com/2013/05/29/using-flags-enumeration-with-aspnet-mvc-and-codefluent-entities

使用這種方法,你會創建實體和枚舉而不是使語言屬性的永久列表之間的關係。

以下主要工作。使用Modeler創建實例時,我無法選擇特定的語言組合。不知道這是否是因爲我沒有經驗,並且沒有設置標誌枚舉或者建模者有缺陷。但我確實設法創建了該方法,並且該部分似乎正在工作。

<cf:enumeration name="Language" multivalue="true" usePersistenceDefaultValue="false" namespace="Demo1" categoryPath="/Demo1"> 
<cf:enumerationValue name="Unspecified" default="true" /> 
<cf:enumerationValue name="EN" /> 
<cf:enumerationValue name="NL" /> 
<cf:enumerationValue name="DE" /> 
</cf:enumeration> 
<cf:entity name="Person" namespace="Demo1"> 
<cf:property name="Id" key="true" /> 
<cf:property name="Languages" usePersistenceDefaultValue="false" typeName="{0}.Language" /> 
<cf:property name="FirstName" /> 
<cf:property name="LastName" /> 
<cf:instance> 
    <cf:instanceValue name="Id">d13447c6-a709-4c87-891d-e83674821915</cf:instanceValue> 
    <cf:instanceValue name="FirstName">Jon</cf:instanceValue> 
    <cf:instanceValue name="LastName">Smith</cf:instanceValue> 
</cf:instance> 
<cf:instance> 
    <cf:instanceValue name="Id">77e3730c-2cc3-457d-8bc0-d9a5e224b96a</cf:instanceValue> 
    <cf:instanceValue name="FirstName">Sam</cf:instanceValue> 
    <cf:instanceValue name="Languages">DE, SP</cf:instanceValue> 
    <cf:instanceValue name="LastName">Newman</cf:instanceValue> 
</cf:instance> 
<cf:method name="LoadPersonThatSpeaksOneOrMoreLanguages" body="LOAD() WHERE Languages &gt; 0" /> 

正如我說帶我在說什麼用一粒鹽。我最終使用了一個實體而不是一個枚舉,但僅僅是因爲這是我更熟悉,並有一個最後期限。

+0

您應該添加一個'None' /'Unspecified' /'未知枚舉中的值爲'0'。在你的情況下,'EN'的值是'0',不能組合使用。也許這就解釋了爲什麼你不能在建模者中用特定的語言組合創建一個實例。 – meziantou

+0

我更新了我的代碼示例中的枚舉以包含未指定。謝謝meziantou! – Dave

2

問題1

PersistentList被設計成簡單的存儲值的集合(整型,字符串,枚舉,...),但不能直接在SQL查詢它們。事實上,PersistentList被翻譯爲數據庫中的NVARCHAR列,並且此列包含像EN|NL(管道分隔值)這樣的值。數據庫引擎不知道如何從字符串中提取單個值。也許你可以使用cf_SplitString函數根據列值創建一個表格並按照你想要的方式做它,但它似乎不是最簡單的解決方案......

根據你的需要,你可以使用一個多值枚舉:

<cf:enumeration name="Language" flags="true"> 
    <cf:enumerationValue name="Unspecified" /> <!-- value=0 --> 
    <cf:enumerationValue name="EN" />   <!-- value=1 --> 
    <cf:enumerationValue name="NL" />   <!-- value=2 --> 
    <cf:enumerationValue name="FR" />   <!-- value=4 --> 
</cf:enumeration> 

您可以CFQL使用它們:

-- Load Persons that speak the specified language 
LOAD(Languages) WHERE (Languages & @Languages) = @Languages 

-- Load Persons that speak at least one of the specified language 
LOAD(Languages) WHERE (Languages & @Languages) <> 0 

當然最新的可能性是創建一個語言實體,使用表值參數。

http://blog.codefluententities.com/2014/07/16/persistent-list/ http://www.softfluent.com/documentation/Enumerations_Overview.html

問題2

從CodeFluent實體official blog

enter image description here enter image description here

+0

因此,我的語言枚舉的值必須是增加2的冪(從1開始),而不是數組的語言參數必須包含與OR邏輯運算符結合的語言?那是一個好主意! – Willem

+0

這就是這個想法。 CodeFluent實體自動設置枚舉值的值。你只需要將'flags'設置爲'true',以便使用2的冪。 – meziantou

相關問題