我有多对多关系设置,需要控制订单。
我有一个拥有以下属性的实体。通过此关系检索时,如何控制组件的顺序?
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"
属性时,它似乎忽略了它。
关于如何控制多对多关系顺序的任何建议?
答案 0 :(得分:3)
当关系是多对多时,CF会将orderBy
语句应用于对象表而不是链接表。因此,从理论上讲,您可以将 dispOrder 列从 CMSPageComponents 链接表移动到 CmsComponent 表,以使其正常工作。
但实际上我希望排序特定于多对多关系(即特定页面),在这种情况下,您可以遵循Peter的建议并创建一个单独的实体,链接其他两个实体并让您定义订单属性。
所以你将拥有3个实体:
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
为真