3

我的模型包含以下枚举和实体:

<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:我怎样才能达到预期的效果?我应该创建一个 Language 实体并指定 Person 和 Language 之间的 1:n 关联吗?我不喜欢有语言实体。或者我可以指定 Languages 属性必须转换为与表值参数 ( cf_type_Person_LoadPersonThatSpeaksOneOrMoreLanguages_0) 相同的类型吗?

问题2:生成的PersonCollection类包含方法LoadPersonThatSpeaksOneOrMoreLanguages。该方法的参数类型为Language[]。而不是一个数组,我想要一个IEnumerable<Language>. 如何在我的 XML 模型中指定它?

4

2 回答 2

2

问题 1

PersistentList旨在存储简单值(int、string、enum、...)的集合,而不是直接在 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 Entities 的官方博客

在此处输入图像描述 在此处输入图像描述

于 2015-10-19T18:54:21.317 回答
1

在处理我研究过但从未实施过的主题时,请接受我所说的话。话虽如此,另一种方法是使用多值枚举(标志)

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

使用这种方法,您将在实体和枚举之间创建关系,而不是使 Languages 属性成为持久列表。

以下主要工作。使用 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" />

正如我所说的那样,我所说的要持保留态度。我最终使用了实体而不是枚举,但这只是因为那是我更熟悉的并且有截止日期。

于 2015-10-19T18:35:22.843 回答