CF ORM多对多关系排序顺序

时间:2013-10-31 23:21:30

标签: orm coldfusion coldbox

我有多对多关系设置,需要控制订单。

我有一个拥有以下属性的实体。通过此关系检索时,如何控制组件的顺序?

property name="Components" fieldtype="many-to-many" cfc="CmsComponent" 
      type="array" 
      singularname="Component" 
      linktable="CMSPageComponents" 
      fkcolumn="page_id" 
      inversejoincolumn="component_id";

我在链接表(CMSPageComponents)中设置了一个名为dispOrder的列。但是当我在上面的属性上设置orderby="dispOrder"orderby="CMSPageComponents.dispOrder"属性时,它似乎忽略了它。

关于如何控制多对多关系顺序的任何建议?

1 个答案:

答案 0 :(得分:3)

当关系是多对多时,CF会将orderBy语句应用于对象表而不是链接表。因此,从理论上讲,您可以将 dispOrder 列从 CMSPageComponents 链接表移动到 CmsComponent 表,以使其正常工作。

但实际上我希望排序特定于多对多关系(即特定页面),在这种情况下,您可以遵循Peter的建议并创建一个单独的实体,链接其他两个实体并让您定义订单属性。

所以你将拥有3个实体:

  1. CmsPage
  2. CmsComponent
  3. CmsPageComponent
  4. CmsPageComponent 可能如下所示:

    <cfcomponent displayname="CmsPageComponent" persistent="true" table="cmsPageComponents">
        <!--- Add a primary key for the link Entity --->
        <cfproperty name="ID" fieldType="id" generator="native">
        <cfproperty name="dispOrder">
        <cfproperty name="page" fieldType="many-to-one" cfc="CmsPage" fkColumn="pageID">
        <cfproperty name="component" fieldType="many-to-one" cfc="CmsComponent" fkColumn="componentID">
        <!--- init() etc --->
    </cfcomponent>
    

    CmsPage 可以与链接实体建立一对多的关系,允许使用dispOrder列进行排序:

    <cfcomponent displayname="CmsPage" persistent="true" table="cmsPages">
        <cfproperty name="ID" fieldType="id" generator="native">
        <cfproperty name="pageComponents" singularName="pageComponent" fieldType="one-to-many" cfc="PageComponent" fkColumn="pageID" orderBy="dispOrder">
        <!--- init() etc --->
    </cfcomponent>
    

    <强>更新 以下显示了如何添加和显示页面组件。不是唯一或最好的方式,只是为了给你一个想法:

    <cfscript>
    transaction{
        //load the page
        page    =   EntityLoadByPK( "CmsPage",1 );
        //load the components we want to add
        component1  =   EntityLoadByPK( "CmsComponent",1 );
        component2  =   EntityLoadByPK( "CmsComponent",2 );
        //create link objects
        pageComponent1  =   EntityNew( "CmsPageComponent" );
        pageComponent2  =   EntityNew( "CmsPageComponent" );
        // link them to the pages and components in the order we want
        pageComponent1.setComponent( component1 );
        pageComponent1.setPage( page );
        pageComponent1.setDispOrder( 2 );
        EntitySave( pageComponent1 );
        pageComponent2.setComponent( component2 );
        pageComponent2.setPage( page );
        pageComponent2.setDispOrder( 1 );
        EntitySave( pageComponent2 );
    }
    //Reload from the database so the order is applied
    EntityReload( page );
    </cfscript>
    <!DOCTYPE html>
    <html>
    <head>
        <title>Test</title>
    </head>
    <body>
        <cfoutput>
            <h2>Page #page.getID()#</h2>
            <ol>
                <cfloop array="#page.getPageComponents()#" index="pageComponent">
                    <cfset component    =   pageComponent.getComponent()>
                    <li>Component ID #component.getID()#, Display Order = #pageComponent.getDispOrder()#)</li>
                </cfloop>
            </ol>
        </cfoutput>
    </body>
    </html>
    

    注意:这假设在Application.cfc

    中ORM设置flushAtRequestEnd为真