0

我正在尝试详细说明 SEARCH CFQL 方法。

我在实体Address中设置了属性TownId或属性TownLabel

  • 如果地址受到来自引用的城镇的影响,则设置TownId 城镇存储在另一个数据库中并且仅由 ID 引用)。
  • 如果没有找到已知城镇,则设置TownLabel 。(例如国外城镇名称)

在我的 SEARCH 方法中,我想查找具有城镇标签的用户,或者是 townLabel 或者来自参考 whoes 名称的可能城镇包含值 townLabel。

长话短说,我的 CFQL 方法如下

SEARCH(string[] townIds, string townLabel) WHERE Adresses.TownId IN (@townIds) OR Adresses.TownLabel LIKE '%'+@townLabel+'%'

尽管使用了 OR 运算符,但生成的 SQL 与 AND 运算符一起出现,如下所示。

我的问题:这正常吗?

CREATE PROCEDURE [dbo].[User_AdvancedSearch]
(
 @townIds [nvarchar] (max) = NULL,
 @townLabel [nvarchar] (256) = NULL,
 @_orderBy0 [nvarchar] (64) = NULL,
 @_orderByDirection0 [bit] = 0
)
AS
SET NOCOUNT ON
DECLARE @sql nvarchar(max), @paramlist nvarchar(max)

SELECT @sql=
'SELECT DISTINCT [User].[User_UserId], [User].[User_Name], [User].[User_Association_AssociationId], [User].[_trackLastWriteTime], [User].[_trackCreationTime], [User].[_trackLastWriteUser], [User].[_trackCreationUser], [User].[_rowVersion] 
    FROM [User]
        LEFT OUTER JOIN [Address] ON ([User].[User_UserId] = [Address].[Address_User_UserId])
    WHERE ((1 = 1) AND (1 = 1))'
SELECT @paramlist = '@townIds nvarchar (max), 
    @townLabel nvarchar (256), 
    @_orderBy0 nvarchar (64), 
    @_orderByDirection0 bit'
IF @townIds IS NOT NULL
    SELECT @sql = @sql + ' AND ([Address].[Address_TownId] IN ((SELECT [Item] FROM [dbo].cf_SplitString(@townIds, nchar(1)))))'
IF @townLabel IS NOT NULL
    SELECT @sql = @sql + ' AND (([Address].[Address_TownLabel] LIKE ((''%'' + @townLabel) + ''%'')))'
EXEC sp_executesql @sql, @paramlist,
    @townIds, 
    @townLabel, 
    @_orderBy0, 
    @_orderByDirection0

RETURN
GO

架构如下

<cf:project defaultNamespace="WcfServices.Model" xmlns:cf="http://www.softfluent.com/codefluent/2005/1" xmlns:cfx="http://www.softfluent.com/codefluent/modeler/2008/1" xmlns:cfps="http://www.softfluent.com/codefluent/producers.sqlserver/2005/1" xmlns:cfom="http://www.softfluent.com/codefluent/producers.model/2005/1" xmlns:cfsps="http://www.softfluent.com/codefluent/producers.sqlpivotscript/2013/1" createDefaultMethodForms="true" createDefaultApplication="false" createDefaultHints="false">
  <cf:import path="Default.Surface.cfp" />
  <cf:entity name="Association" namespace="Example.Model.Association" categoryPath="/WcfServices.Model">
    <cf:property name="AssociationId" key="true" persistenceEnforce="true" />
    <cf:property name="Label" persistenceEnforce="true" />
    <cf:property name="Users" typeName="Example.Model.Association.UserCollection" relationPropertyName="Association" />
  </cf:entity>
  <cf:producer name="SQL Server" typeName="CodeFluent.Producers.SqlServer.SqlServerProducer, CodeFluent.Producers.SqlServer">
    <cf:configuration produceViews="true" targetDirectory="..\WcfServices.persistence" cfx:targetProject="..\WcfServices.persistence\WcfServices.persistence.sqlproj" cfx:targetProjectLayout="Update, DontRemove" />
  </cf:producer>
  <cf:producer name="Business Object Model (BOM)" typeName="CodeFluent.Producers.CodeDom.CodeDomProducer, CodeFluent.Producers.CodeDom">
    <cf:configuration compileWithVisualStudio="true" compile="false" codeDomProviderTypeName="CSharp" targetDirectory="..\WcfServices.model" cfx:targetProject="..\WcfServices.model\WcfServices.model.csproj" cfx:targetProjectLayout="Update">
    </cf:configuration>
  </cf:producer>
  <cf:entity name="User" namespace="Example.Model.Association" categoryPath="/WcfServices.Model">
    <cf:property name="UserId" key="true" persistenceEnforce="true" />
    <cf:property name="Name" persistenceEnforce="true" />
    <cf:property name="Association" typeName="Example.Model.Association.Association" relationPropertyName="Users" />
    <cf:property name="Adresses" typeName="Example.Model.Association.AddressCollection" relationPropertyName="User" persistenceEnforce="true" />
    <cf:method name="AdvancedSearch" body="SEARCH(string[] townIds, string townLabel) WHERE Adresses.TownId IN (@townIds) OR Adresses.TownLabel LIKE '%%'+@townLabel+'%%'" />
  </cf:entity>
  <cf:producer name="SQL Server Pivot Script" typeName="CodeFluent.Producers.SqlServer.SqlPivotScriptProducer, CodeFluent.Producers.SqlServer">
    <cf:configuration targetDirectory="..\WcfServices.web" cfx:targetProject="..\WcfServices.web\WcfServices.web.csproj" cfx:targetProjectLayout="Update" />
  </cf:producer>
  <cf:entity name="Address" namespace="Example.Model.Association" categoryPath="/WcfServices.Model">
    <cf:property name="AddressId" key="true" persistenceEnforce="true" />
    <cf:property name="Line" persistenceEnforce="true" />
    <cf:property name="User" typeName="Example.Model.Association.User" relationPropertyName="Adresses" persistenceEnforce="true" />
    <cf:property name="TownLabel" />
    <cf:property name="TownId" typeName="guid" />
  </cf:entity>
</cf:project>

编辑 15/09/2016 - 添加原始 CFQL + 架构。

原始CFQL方法:

SEARCH (string firstname, string name, int[] groups, string postalCode, string townLabel, string mail, string[] townId, guid structureId, guid countryId) WHERE Firstname LIKE '%'+@firstname+'%' AND Name LIKE '%'+@name+'%' AND (Address.PostalCode LIKE '%'+@postalCode+'%' OR StructureContacts.Address.PostalCode LIKE '%'+@postalCode+'%') AND ( Address.TownLabel LIKE '%'+@townLabel+'%' OR StructureContacts.Address.TownLabel LIKE '%'+@townLabel+'%' OR Address.TownId IN (@townId) OR StructureContacts.Address.TownId IN(@townId)) AND (StructureContacts.Groups.Value IN (@groups) OR Groups.Value IN (@groups)) AND StructureContacts.Structure.StructureId = @structureId and (Address.Email LIKE '%'+@mail+'%' OR StructureContacts.Address.Email LIKE '%'+@mail+'%') AND (Address.CountryId = @countryId OR StructureContacts.Address.CountryId = @countryId) order by Name, Firstname

架构:

<cf:project defaultNamespace="Example.Models" xmlns:cf="http://www.softfluent.com/codefluent/2005/1">
  <cf:enumeration name="enumStructureType" namespace="Example.Models.Contact.Structure" categoryPath="/RH">
    <cf:enumerationValue name="ENTERPRISE" />
    <cf:enumerationValue name="ASSOCIATION" />
    <cf:enumerationValue name="OTHER_ASSOCIATION" />
    <cf:enumerationValue name="SUPPLIER" />
    <cf:enumerationValue name="PUBLIC_ORGANIZATION" />
  </cf:enumeration>
  <cf:entity name="Structure" defaultUsePersistenceDefaultValue="false" defaultPersistenceEnforce="false" namespace="Example.Models.Contact.Structure" categoryPath="/RH" storeName="ExampleStoreName">
    <cf:property name="StructureId" key="true" />
    <cf:property name="Sigle" />
    <cf:property name="CorporateName" />
    <cf:property name="Code" />
    <cf:property name="Comment">
      <cf:rule typeName="StringValidate" maxLength="2000" />
    </cf:property>
    <cf:property name="Siret" xmlns:cf="http://www.softfluent.com/codefluent/2005/1" collectionKey="false">
      <cf:rule typeName="RegularExpressionValidate" expression="[\d]{14,14}" />
    </cf:property>
    <cf:property name="Type" xmlns:cf="http://www.softfluent.com/codefluent/2005/1" defaultValue="EstablishmentType.PRINCIPAL" typeName="{0}.Contact.Structure.enumStructureType" collectionKey="false" />
    <cf:property name="Groups" set="true" cascadeSave="After" cascadeDelete="Before" typeName="{0}.Contact.Contact.GroupCollection" />
    <cf:property name="ApeId" typeName="guid" />
    <cf:property name="Address" cascadeSave="After" cascadeDelete="Before" typeName="{0}.Contact.Contact.Address" relationSchema="Contact" />
    <cf:property name="EstablishmentType" typeName="{0}.Contact.Structure.enumEstablishmentType" />
    <cf:property name="ParentStructure" readOnSave="true" typeName="{0}.Contact.Structure.Structure" relationPropertyName="ChildrenStructures" />
    <cf:property name="ChildrenStructures" set="true" cascadeSave="After" cascadeDelete="Before" typeName="{0}.Contact.Structure.StructureCollection" relationPropertyName="ParentStructure" />
    <cf:property name="OpeningHours" maxLength="2000" />
    <cf:method name="SimpleSearchStructures" body="SEARCH (string keyword) WHERE CorporateName LIKE '%%'+@keyword+'%%' OR Code LIKE '%%'+@keyword+'%%' OR Comment LIKE '%%'+@keyword+'%%' OR Sigle LIKE '%%'+@keyword+'%%' OR Siret LIKE '%%'+@keyword+'%%' OR Address.Email LIKE '%%'+@keyword+'%%' ORDER BY CorporateName" />
    <cf:method name="AdvancedSearchStructures" body="SEARCH (string corporateName, string email, string postalCode, string townLabel, string[] townIds, int[] groups, guid countryId, int[] types) WHERE CorporateName LIKE '%%'+@corporateName+'%%' AND Address.Email LIKE '%%'+@email+'%%'  AND (Address.TownLabel LIKE '%%'+@townLabel+'%%' OR Address.TownId IN (@townIds)) AND Address.PostalCode LIKE '%%'+@postalCode+'%%' AND Address.CountryId = @countryId AND Groups.Value IN (@groups) AND Type IN (@types) ORDER BY CorporateName" />
    <cf:rule typeName="OnBeforeSave" methodName="BeforeSave" />
    <cf:method name="DeleteById" body="DELETE(guid id) WHERE StructureId = @id" />
  </cf:entity>
  <cf:entity name="StructureAssociation" baseTypeName="Example.Models.Contact.Structure.Structure" namespace="Example.Models.Contact.Structure" categoryPath="/Example.Models" storeName="ExampleStoreName">
    <cf:property name="ParutionDateOJ" xmlns:cf="http://www.softfluent.com/codefluent/2005/1" typeName="date" persistenceEnforce="true" collectionKey="false" />
    <cf:property name="BasinId" xmlns:cf="http://www.softfluent.com/codefluent/2005/1" typeName="guid" relationSchema="Contact" persistenceEnforce="true" collectionKey="false" />
    <cf:property name="ReceiptNum" xmlns:cf="http://www.softfluent.com/codefluent/2005/1" persistenceEnforce="true" collectionKey="false" />
    <cf:property name="PrefectureId" typeName="guid" persistenceEnforce="true" />
    <cf:property name="CreationDate" typeName="date" persistenceEnforce="true" />
    <cf:property name="CartePecheAappmaId" persistenceEnforce="true" />
    <cf:method name="LoadAssociationStructure" body="LOADONE WHERE EstablishmentType = 3" />
  </cf:entity>
  <cf:entity name="StructureContact" defaultUsePersistenceDefaultValue="false" setType="List" namespace="Example.Models.Contact.Structure" categoryPath="/RH" storeName="ExampleStoreName">
    <cf:property name="Function" defaultValue="enumFunctionType.PRESIDENT" typeName="{0}.Contact.Structure.enumFunctionType" persistenceEnforce="true" collectionKey="false" />
    <cf:property name="StartDateFunction" usePersistenceDefaultValue="true" typeName="date" persistenceEnforce="true" collectionKey="false" />
    <cf:property name="EndDateFunction" usePersistenceDefaultValue="true" typeName="date" persistenceEnforce="true" collectionKey="false" />
    <cf:property name="Contact" typeName="{0}.Contact.Contact.Contact" relationPropertyName="StructureContacts" relationSchema="Contact" persistenceEnforce="true" />
    <cf:property name="Address" cascadeSave="After" cascadeDelete="Before" typeName="{0}.Contact.Contact.Address" relationSchema="Contact" persistenceEnforce="true" />
    <cf:property name="Groups" set="true" cascadeSave="After" cascadeDelete="Before" typeName="{0}.Contact.Contact.GroupCollection" persistenceEnforce="true" />
    <cf:property name="DocumentUrl" typeName="guid" persistenceEnforce="true" />
    <cf:property name="Structure" typeName="{0}.Contact.Structure.Structure" persistenceEnforce="true">
      <cf:attribute name="Newtonsoft.Json.JsonIgnore" class="" />
    </cf:property>
    <cf:property name="StructureContactId" key="true" persistenceEnforce="true" />
    <cf:property name="AdditionalDate" usePersistenceDefaultValue="true" typeName="date" persistenceEnforce="true" />
    <cf:property name="DocumentName" persistenceEnforce="true" />
    <cf:method name="LoadBoardMembers" body="LOAD (int[] functions) WHERE Function IN (@functions)" />
  </cf:entity>
  <cf:entity name="StructureEnterprise" baseTypeName="Example.Models.Contact.Structure.Structure" namespace="Example.Models.Contact.Structure" categoryPath="/Example.Models" storeName="ExampleStoreName">
    <cf:property name="VATNum" xmlns:cf="http://www.softfluent.com/codefluent/2005/1" persistenceEnforce="true" collectionKey="false" />
  </cf:entity>
  <cf:entity name="StructureOtherAssociation" baseTypeName="Example.Models.Contact.Structure.Structure" namespace="Example.Models.Contact.Structure" categoryPath="/Example.Models" storeName="ExampleStoreName">
    <cf:property name="ReceiptNum" xmlns:cf="http://www.softfluent.com/codefluent/2005/1" persistenceEnforce="true" collectionKey="false" />
    <cf:property name="SkillTerritoryType" typeName="{0}.Contact.Structure.enumStructureSkillTerritoryType" persistenceEnforce="true" />
  </cf:entity>
  <cf:entity name="Address" defaultUsePersistenceDefaultValue="false" namespace="Example.Models.Contact.Contact" categoryPath="/RH" persistenceName="Address" storeName="ExampleStoreName">
    <cf:property name="AddressId" key="true" persistenceEnforce="true" />
    <cf:property name="Line1" persistenceEnforce="true" />
    <cf:property name="Line2" persistenceEnforce="true" />
    <cf:property name="IsActive" typeName="bool" persistenceEnforce="true" />
    <cf:property name="Landline" persistenceEnforce="true" />
    <cf:property name="Email" persistenceEnforce="true">
      <cf:rule typeName="EmailValidate" />
    </cf:property>
    <cf:property name="Fax" persistenceEnforce="true" />
    <cf:property name="Website" persistenceEnforce="true" />
    <cf:property name="Mobile" persistenceEnforce="true" />
    <cf:property name="DirectLine" persistenceEnforce="true" />
    <cf:property name="ProfessionalLine" persistenceEnforce="true" />
    <cf:property name="TownId" typeName="guid" persistenceEnforce="true" />
    <cf:property name="TownLabel" persistenceEnforce="true" />
    <cf:property name="CountryId" typeName="guid" persistenceEnforce="true" />
    <cf:property name="PostalCode" persistenceEnforce="true" />
    <cf:rule typeName="OnBeforeSave" methodName="BeforeSave" />
  </cf:entity>
  <cf:entity name="Contact" defaultUsePersistenceDefaultValue="false" namespace="Example.Models.Contact.Contact" categoryPath="/RH" persistenceName="Contact" storeName="ExampleStoreName">
    <cf:property name="Name" persistenceEnforce="true" />
    <cf:property name="Firstname" persistenceEnforce="true" />
    <cf:property name="Civility" defaultValue="CivilityContact.Mr" typeName="{0}.Global.Civility" persistenceEnforce="true" />
    <cf:property name="DateOfBirth" serializationNullable="true" modelNullable="true" typeName="date" persistenceEnforce="true" />
    <cf:property name="Comment" persistenceEnforce="true">
      <cf:rule typeName="StringValidate" maxLength="2000" />
    </cf:property>
    <cf:property name="ContactId" key="true" persistenceEnforce="true" />
    <cf:property name="StructureContacts" set="true" cascadeSave="After" cascadeDelete="Before" typeName="{0}.Contact.Structure.StructureContactCollection" relationPropertyName="Contact" relationSchema="Contact" persistenceEnforce="true" />
    <cf:property name="Address" cascadeSave="After" cascadeDelete="Before" typeName="{0}.Contact.Contact.Address" relationSchema="Contact" persistenceEnforce="true" />
    <cf:property name="TownOfBirthLabel" persistenceEnforce="true" />
    <cf:property name="TownIdOfBirth" typeName="guid" persistenceEnforce="true" />
    <cf:property name="CountryIdOfBirth" typeName="guid" persistenceEnforce="true" />
    <cf:property name="DepartmentIdOfBirth" typeName="guid" persistenceEnforce="true" />
    <cf:property name="PostalCode" persistenceEnforce="true" />
    <cf:property name="Groups" set="true" cascadeSave="After" cascadeDelete="Before" typeName="{0}.Contact.Contact.GroupCollection" persistenceEnforce="true" />
    <cf:property name="CartePecheMemberId" persistenceEnforce="true" />
    <cf:method name="AdvancedSearchContactsTownLabel" body="SEARCH (string firstname, string name, int[] groups, string postalCode, string townLabel, string mail, string[] townId, guid structureId, guid countryId) WHERE Firstname LIKE '%%'+@firstname+'%%' AND Name LIKE '%%'+@name+'%%' AND (Address.PostalCode LIKE '%%'+@postalCode+'%%' OR StructureContacts.Address.PostalCode LIKE '%%'+@postalCode+'%%') AND ( Address.TownLabel LIKE '%%'+@townLabel+'%%' OR StructureContacts.Address.TownLabel LIKE '%%'+@townLabel+'%%' OR Address.TownId IN (@townId) OR StructureContacts.Address.TownId IN(@townId)) AND (StructureContacts.Groups.Value IN (@groups) OR Groups.Value IN (@groups)) AND StructureContacts.Structure.StructureId = @structureId and (Address.Email LIKE '%%'+@mail+'%%' OR StructureContacts.Address.Email LIKE '%%'+@mail+'%%') AND (Address.CountryId = @countryId OR StructureContacts.Address.CountryId = @countryId) order by Name, Firstname" />
    <cf:method name="SimpleSearchContacts" body="SEARCH(string keywords) WHERE Firstname LIKE '%%'+@keywords+'%%' OR Name LIKE '%%'+@keywords+'%%' OR Address.Email LIKE '%%'+@keywords+'%%' OR StructureContacts.Address.Email LIKE '%%'+@keywords+'%%' order by Name, Firstname" />
    <cf:rule typeName="OnBeforeSave" methodName="BeforeSave" />
    <cf:method name="SearchContactByName" body="SEARCH(string nameOrFirstName, int[] functions) WHERE (Name LIKE '%%'+@nameOrFirstName+'%%' OR Firstname LIKE '%%'+@nameOrFirstName+'%%') AND StructureContacts.Function IN (@functions)" />
    <cf:method name="LoadContactsByDateFunction" body="LOAD (date currentDate, int[] functions) WHERE StructureContacts.Function IN (@functions) AND ( StructureContacts.StartDateFunction &lt;= @currentDate OR NOT StructureContacts.StartDateFunction EXISTS )&#xD;&#xA; AND ( StructureContacts.EndDateFunction &gt; @currentDate OR NOT StructureContacts.EndDateFunction EXISTS )" />
    <cf:method name="DeleteById" body="DELETE(guid id) WHERE ContactId = @id" />
    <cf:method name="AdvancedSearchContactTownId" body="SEARCH (string firstname, string name, int[] groups, string postalCode, string townLabel, string mail, string[] townId, guid structureId, guid countryId) WHERE Firstname LIKE '%%'+@firstname+'%%' AND Name LIKE '%%'+@name+'%%' AND (Address.PostalCode LIKE '%%'+@postalCode+'%%' OR StructureContacts.Address.PostalCode LIKE '%%'+@postalCode+'%%')  AND (Address.TownId IN (@townId) OR StructureContacts.Address.TownId IN(@townId) ) AND (StructureContacts.Groups.Value IN (@groups) OR Groups.Value IN (@groups)) AND StructureContacts.Structure.StructureId = @structureId and (Address.Email LIKE '%%'+@mail+'%%' OR StructureContacts.Address.Email LIKE '%%'+@mail+'%%') AND (Address.CountryId = @countryId OR StructureContacts.Address.CountryId = @countryId) order by Name, Firstname" />
  </cf:entity>
  <cf:entity name="Group" defaultUsePersistenceDefaultValue="false" namespace="Example.Models.Contact.Contact" categoryPath="/RH" storeName="ExampleStoreName">
    <cf:property name="GroupId" key="true" persistenceEnforce="true" />
    <cf:property name="Value" defaultValue="enumGroupType.DGS" typeName="int" persistenceEnforce="true" />
  </cf:entity>
  <cf:entity name="StructureSupplier" baseTypeName="Example.Models.Contact.Structure.Structure" namespace="Example.Models.Contact.Structure" categoryPath="/Example.Models" storeName="ExampleStoreName">
    <cf:property name="CartePecheDepositaireId" persistenceEnforce="true" />
    <cf:property name="NumberExt" persistenceEnforce="true" />
    <cf:property name="DocumentUrl" persistenceEnforce="true" />
    <cf:property name="DocumentName" persistenceEnforce="true" />
    <cf:property name="IsKeyAccount" typeName="bool" persistenceEnforce="true" />
    <cf:property name="ConventionDate" typeName="date" persistenceEnforce="true" />
  </cf:entity>
  <cf:enumeration name="enumEstablishmentType" namespace="Example.Models.Contact.Structure" categoryPath="/Example.Models">
    <cf:enumerationValue name="HEAD_OFFICE" />
    <cf:enumerationValue name="SECONDARY" />
    <cf:enumerationValue name="DELEGATION" />
    <cf:enumerationValue name="ASSOCIATION" />
  </cf:enumeration>
  <cf:enumeration name="enumFunctionType" namespace="Example.Models.Contact.Structure" categoryPath="/Example.Models">
    <cf:enumerationValue name="DIRECTOR" />
    <cf:enumerationValue name="EMPLOYEE" />
    <cf:enumerationValue name="ELECTED" />
    <cf:enumerationValue name="VOLUNTEER" />
    <cf:enumerationValue name="INDIVIDUAL" />
    <cf:enumerationValue name="PRESIDENT" />
    <cf:enumerationValue name="VICE_PRESIDENT" />
    <cf:enumerationValue name="TREASURER" />
    <cf:enumerationValue name="SECRETARY" />
    <cf:enumerationValue name="BOARD_MEMBER" />
    <cf:enumerationValue name="LEGAL_MEMBER" />
    <cf:enumerationValue name="BY_LAW_MEMBER" />
    <cf:enumerationValue name="ACCOUNT_INSPECTOR" />
    <cf:enumerationValue name="RESELLER" />
    <cf:enumerationValue name="OWNER" />
    <cf:enumerationValue name="CONTRACTOR" />
    <cf:enumerationValue name="GENERAL_CONTRACTOR" />
    <cf:enumerationValue name="CONTRACTING_AUTHORITY" />
    <cf:enumerationValue name="LESSOR" />
    <cf:enumerationValue name="OTHER" />
    <cf:enumerationValue name="MEMBER" />
  </cf:enumeration>
  <cf:enumeration name="enumStructureSkillTerritoryType" namespace="Example.Models.Contact.Structure" categoryPath="/Example.Models">
    <cf:enumerationValue name="LOCAL" />
    <cf:enumerationValue name="DEPARTEMENTAL" />
    <cf:enumerationValue name="REGIONAL" />
    <cf:enumerationValue name="NATIONAL" />
  </cf:enumeration>
  <cf:entity name="StructurePublicOrganization" baseTypeName="Example.Models.Contact.Structure.Structure" namespace="Example.Models.Contact.Structure" categoryPath="/Example.Models" storeName="ExampleStoreName">
    <cf:property name="ReceiptNum" persistenceEnforce="true" />
  </cf:entity>
</cf:project>

生成的 SQL(注意 townLabel 参数中额外的 AND)

CREATE PROCEDURE [Contact].[Contact_AdvancedSearchContactsTownLabel]
(
 @firstname [nvarchar] (256) = NULL,
 @name [nvarchar] (256) = NULL,
 @groups [Contact].[cf_type_Contact_AdvancedSearchContactsTownLabel_2] READONLY,
 @postalCode [nvarchar] (256) = NULL,
 @townLabel [nvarchar] (256) = NULL,
 @mail [nvarchar] (256) = NULL,
 @townId [nvarchar] (max) = NULL,
 @structureId [uniqueidentifier] = NULL,
 @countryId [uniqueidentifier] = NULL,
 @_orderBy0 [nvarchar] (64) = NULL,
 @_orderByDirection0 [bit] = 0
)
AS
SET NOCOUNT ON
DECLARE @_c_groups int; SELECT @_c_groups= COUNT(*) FROM @groups
DECLARE @sql nvarchar(max), @paramlist nvarchar(max)

SELECT @sql=
'SELECT DISTINCT [Contact].[Contact].[Contact_Name], [Contact].[Contact].[Contact_Firstname], [Contact].[Contact].[Contact_Civility], [Contact].[Contact].[Contact_DateOfBirth], [Contact].[Contact].[Contact_Comment], [Contact].[Contact].[Contact_ContactId], [Contact].[Contact].[Contact_Address_AddressId], [Contact].[Contact].[Contact_TownOfBirthLabel], [Contact].[Contact].[Contact_TownIdOfBirth], [Contact].[Contact].[Contact_CountryIdOfBirth], [Contact].[Contact].[Contact_DepartmentIdOfBirth], [Contact].[Contact].[Contact_PostalCode], [Contact].[Contact].[Contact_CartePecheMemberId], [Contact].[Contact].[_trackLastWriteTime], [Contact].[Contact].[_trackCreationTime], [Contact].[Contact].[_trackLastWriteUser], [Contact].[Contact].[_trackCreationUser], [Contact].[Contact].[_rowVersion] 
    FROM [Contact].[Contact]
        LEFT OUTER JOIN [Contact].[Address] ON ([Contact].[Contact].[Contact_Address_AddressId] = [Contact].[Address].[Address_AddressId])
        LEFT OUTER JOIN [Contact].[StructureContact] ON ([Contact].[Contact].[Contact_ContactId] = [Contact].[StructureContact].[StructureContact_Contact_ContactId])
                LEFT OUTER JOIN [Contact].[Address] [Address$1] ON ([Contact].[StructureContact].[StructureContact_Address_AddressId] = [Address$1].[Address_AddressId])
                LEFT OUTER JOIN [Contact].[StructureContact_Groups_Group] ON ([Contact].[StructureContact].[StructureContact_StructureContactId] = [Contact].[StructureContact_Groups_Group].[StructureContact_StructureContactId])
                        LEFT OUTER JOIN [Contact].[Group] ON ([Contact].[StructureContact_Groups_Group].[Group_GroupId] = [Contact].[Group].[Group_GroupId])
                LEFT OUTER JOIN [Contact].[Structure] ON ([Contact].[StructureContact].[StructureContact_Structure_StructureId] = [Contact].[Structure].[Structure_StructureId])
        LEFT OUTER JOIN [Contact].[Address] [Address$2] ON ([Contact].[Contact].[Contact_Address_AddressId] = [Address$2].[Address_AddressId])
        LEFT OUTER JOIN [Contact].[Contact_Groups_Group] ON ([Contact].[Contact].[Contact_ContactId] = [Contact].[Contact_Groups_Group].[Contact_ContactId])
                LEFT OUTER JOIN [Contact].[Group] [Group$1] ON ([Contact].[Contact_Groups_Group].[Group_GroupId] = [Group$1].[Group_GroupId])
        LEFT OUTER JOIN [Contact].[Address] [Address$3] ON ([Contact].[Contact].[Contact_Address_AddressId] = [Address$3].[Address_AddressId]) 
    WHERE (((1 = 1) AND ((1 = 1) AND ((1 = 1) AND ((1 = 1) AND ((1 = 1) AND ((1 = 1) AND ((1 = 1) AND (1 = 1)))))))) AND (1 = 1))'
SELECT @paramlist = '@firstname nvarchar (256), 
    @name nvarchar (256), 
    @groups [Contact].[cf_type_Contact_AdvancedSearchContactsTownLabel_2] READONLY, 
    @postalCode nvarchar (256), 
    @townLabel nvarchar (256), 
    @mail nvarchar (256), 
    @townId nvarchar (max), 
    @structureId uniqueidentifier, 
    @countryId uniqueidentifier, 
    @_orderBy0 nvarchar (64), 
    @_orderByDirection0 bit'
IF @firstname IS NOT NULL
    SELECT @sql = @sql + ' AND (([Contact].[Contact].[Contact_Firstname] LIKE ((''%'' + @firstname) + ''%'')))'
IF @name IS NOT NULL
    SELECT @sql = @sql + ' AND (([Contact].[Contact].[Contact_Name] LIKE ((''%'' + @name) + ''%'')))'
IF @_c_groups > 0
    SELECT @sql = @sql + ' AND (([Contact].[Group].[Group_Value] IN ((SELECT * FROM @groups)) OR [Group$1].[Group_Value] IN ((SELECT * FROM @groups))))'
IF @postalCode IS NOT NULL
    SELECT @sql = @sql + ' AND ((([Contact].[Address].[Address_PostalCode] LIKE ((''%'' + @postalCode) + ''%'')) OR ([Address$1].[Address_PostalCode] LIKE ((''%'' + @postalCode) + ''%''))))'
IF @townLabel IS NOT NULL
    SELECT @sql = @sql + ' AND ((([Address$2].[Address_TownLabel] LIKE ((''%'' + @townLabel) + ''%'')) OR (([Contact].[Address].[Address_TownLabel] LIKE ((''%'' + @townLabel) + ''%'')) OR ([Contact].[Address].[Address_TownId] IN ((SELECT [Item] FROM [dbo].cf_SplitString(@townId, nchar(1)))) OR [Contact].[Address].[Address_TownId] IN ((SELECT [Item] FROM [dbo].cf_SplitString(@townId, nchar(1))))))) AND ([Contact].[Address].[Address_TownLabel] LIKE ((''%'' + @townLabel) + ''%'')))'
IF @mail IS NOT NULL
    SELECT @sql = @sql + ' AND ((([Address$3].[Address_Email] LIKE ((''%'' + @mail) + ''%'')) OR ([Contact].[Address].[Address_Email] LIKE ((''%'' + @mail) + ''%''))))'
IF @townId IS NOT NULL
    SELECT @sql = @sql + ' AND (([Contact].[Address].[Address_TownId] IN ((SELECT [Item] FROM [dbo].cf_SplitString(@townId, nchar(1)))) OR [Contact].[Address].[Address_TownId] IN ((SELECT [Item] FROM [dbo].cf_SplitString(@townId, nchar(1))))))'
IF @structureId IS NOT NULL
    SELECT @sql = @sql + ' AND (([Contact].[Structure].[Structure_StructureId] = @structureId))'
IF @countryId IS NOT NULL
    SELECT @sql = @sql + ' AND ((([Contact].[Address].[Address_CountryId] = @countryId) OR ([Contact].[Address].[Address_CountryId] = @countryId)))'
SELECT @sql = @sql + ' ORDER BY [Contact].[Contact].[Contact_Name] ASC,[Contact].[Contact].[Contact_Firstname] ASC'
EXEC sp_executesql @sql, @paramlist,
    @firstname, 
    @name, 
    @groups, 
    @postalCode, 
    @townLabel, 
    @mail, 
    @townId, 
    @structureId, 
    @countryId, 
    @_orderBy0, 
    @_orderByDirection0

RETURN
GO

编辑 2016 年 9 月 16 日 - 找到可能的解决方法。

我发现了两种可能的解决方法:

  • 首先是使用其余参数(没有townId,没有townLabel)有一个更简单的搜索方法,并使用LINQ机制在内存中重新过滤。

  • 其次是在 RAW 方法中使用生成的代码并对其进行调整以使其按照我们想要的方式工作。

4

1 回答 1

1

Search方法很难生成。实际上,生产者必须通过参数拆分方法体。然后它创建IF @param IS NOT NULL语句并使用运算符将​​它们组合起来(默认情况下AND)。如果要更改此运算符,可以在方法中添加以下 xml 属性:

<cf:method cfps:searchOperation="OR" ... />

如果您没有太多参数(1 或 2),您可以使用带有可为空参数的 LOAD 方法:

<cf:method name="LoadNullable" body="LOAD(string text1, string text2) WHERE Name = @text1 AND Name = @text2">
  <cf:parameter nullable="True" name="text1" modelNullable="False" />
</cf:method>

生成的代码如下所示:

CREATE PROCEDURE [dbo].[Customer_LoadNullable]
(
 @text1 [nvarchar] (256) = NULL,
 @text2 [nvarchar] (256)
)
AS
SET NOCOUNT ON
IF(@text1 IS NULL)
BEGIN
    SELECT [Customer].[Customer_Id], [Customer].[Customer_Name]
        FROM [Customer] 
        WHERE ([Customer].[Customer_Name] = @text2)
END
ELSE
BEGIN
    SELECT [Customer].[Customer_Id], [Customer].[Customer_Name]
        FROM [Customer] 
        WHERE (([Customer].[Customer_Name] = @text1) AND ([Customer].[Customer_Name] = @text2))
END

这样你对 and 没有任何问题ORAND但这不适用于具有许多可为空参数的方法。

于 2016-09-15T12:38:05.923 回答