1

我和这个问题有同样的问题(完全一样的需要):How can I declare a Clustered key on a many-to-many relationship table in CodeFluent Entities with Sql Server Producer

我尝试使用方面,但我不确定我应该如何设置配置。

我应该为我cfps:hint="CLUSTERED"的两个表添加吗?我试过了,但我仍然得到同样的错误

SQL80001:“CLUSTERED”附近的语法不正确。

或者也许我的方面没有正确设置。(这是我第一次使用方面)。

可能是产品本身包含的好东西。

=> 更新 => 我仍然有同样的问题。键没有聚集在关系表上。它不是完全相同的关系。

这是我的模型(摘录):

<cf:entity name="Hotel" namespace="Marmara">
  <cf:property name="ProductCode" cfps:hint="CLUSTERED" key="true" typeName="string" />
  <cf:property name="Hotels" typeName="Marmara.BookingCollection" />
  <cf:property name="Name" />
  <cf:property name="Rating" typeName="decimal" />
</cf:entity>

<cf:entity name="Fly" namespace="Marmara">
  <cf:property name="TakeOffDate" cfps:hint="CLUSTERED" key="true" typeName="date" />
  <cf:property name="Bookings" typeName="Marmara.BookingCollection" />
</cf:entity>

<cf:entity name="Booking" setType="List" trackingModes="None" namespace="Marmara">
  <cf:property name="Hotel" key="true" typeName="Marmara.Hotel" />
  <cf:property name="Fly" key="true" typeName="Marmara.Fly" />
  <cf:property name="Price" typeName="int" />
  <cf:property name="AvailableSeat" typeName="int" />
  <cf:property name="RunTimeDate" key="true" typeName="Marmara.RunTimeDate" />
</cf:entity>

<cf:entity name="RunTimeDate" namespace="Marmara">
  <cf:property name="Date" cfps:hint="CLUSTERED" key="true" typeName="datetime" />
  <cf:property name="RunTimeDates" typeName="Marmara.BookingCollection" />
</cf:entity>

这是我的方面的设置:

<cf:pattern path="SampleAspect.cfp" step="start" name="Sample Aspect" />
4

1 回答 1

0

这是一个示例模型:

<cf:pattern path="ClusteredIndexAspect.xml" step="Start" name="ClusteredIndex" />

<cf:entity name="Student">
  <cf:property name="Id" cfps:hint="CLUSTERED" key="true" />
  <cf:property name="Name" />
  <cf:property name="Courses" typeName="{0}.CourseCollection" relationPropertyName="Students" />
</cf:entity>

<cf:entity name="Course">
  <cf:property name="Id" cfps:hint="CLUSTERED" key="true" />
  <cf:property name="Name" />
  <cf:property name="Students" typeName="{0}.StudentCollection" relationPropertyName="Courses" />
</cf:entity>

ClusteredIndexAspect.xml文件(我只是添加cf:pattern标签):

<cf:project xmlns:cf="http://www.softfluent.com/codefluent/2005/1" defaultNamespace="ClusteredHint">
    <cf:pattern name="ClusteredIndex" namespaceUri="http://www.softfluent.com/samples/clustered-index" preferredPrefix="_ci" step="Start">
        <cf:message class="_doc">
            Clustered Index Aspect
        </cf:message>
    </cf:pattern>

    <!-- assembly references -->
    <?code @reference name="CodeFluent.Producers.SqlServer.dll" ?>
    <?code @reference name="CodeFluent.Runtime.Database.dll" ?>

    <!-- namespace includes -->
    <?code @namespace name="System" ?>
    <?code @namespace name="System.Collections.Generic" ?>
    <?code @namespace name="CodeFluent.Model.Code" ?>
    <?code @namespace name="CodeFluent.Model.Persistence" ?>
    <?code @namespace name="CodeFluent.Model.Code" ?>

    <!-- add global code to listen to inference steps -->
    <?code 
        Project.StepChanging += (sender1, e1) =>
        {
            if (e1.Step == ImportStep.End) // hook before production begins (end of inference pipeline)
            {
                var modifiedTables = ProjectHandler.AddClusteredHint(Project);
                // get sql server producer and hook on production events
                var sqlProducer = Project.Producers.GetProducerInstance<CodeFluent.Producers.SqlServer.SqlServerProducer>();
                sqlProducer.Production += (sender, e) =>
                {
                    // determine what SQL file has been created
                    // we want to remove hints once the table_diffs has been created, before relations_add is created
                    string script = e.GetDictionaryValue("filetype", null);
                    if (script == "TablesDiffsScript")
                    {
                        ProjectHandler.RemoveClusteredHint(modifiedTables);
                    }
                };
            }
        };
    ?>

    <!-- add member code to handle inference modification -->
    <?code @member
    public class ProjectHandler
    {
        public static IList<Table> AddClusteredHint(Project project)
        {
            if(project == null)
              throw new ArgumentNullException("project");

            var list = new List<Table>();
            foreach (var table in project.Database.Tables)
            {     
                // we're only interested by tables inferred from M:M relations
                if (table.Relation == null || table.Relation.RelationType != RelationType.ManyToMany)
                    continue;

                // check this table definition is ok for us
                if (table.RelationKeyColumns == null || table.RelationRelatedKeyColumns == null || table.RelationKeyColumns.Count < 1 || table.RelationRelatedKeyColumns.Count < 1)
                  continue;

                // check clustered is declared on both sides
                string keyHint = GetSqlServerProducerHint(table.RelationKeyColumns[0].Property) ?? "";
                string relatedKeyHint = GetSqlServerProducerHint(table.RelationKeyColumns[0].Property) ?? "";

                if (keyHint.IndexOf("clustered", StringComparison.OrdinalIgnoreCase) < 0 ||
                    relatedKeyHint.IndexOf("clustered", StringComparison.OrdinalIgnoreCase) < 0)
                {
                  continue;
                }

                table.PrimaryKey.Elements[0].SetAttribute("hint", CodeFluent.Producers.SqlServer.Constants.SqlServerProducerNamespaceUri, "clustered");

                // remember this table
                list.Add(table);
            }
            return list;
        }

        public static void RemoveClusteredHint(IEnumerable<Table> list)
        {
            foreach (var table in list)
            {
                table.PrimaryKey.Elements[0].RemoveAttribute("hint", CodeFluent.Producers.SqlServer.Constants.SqlServerProducerNamespaceUri);
            }
        }

        // helper method to read XML element's hint attribute in the SQL Server Producer namespace
        private static string GetSqlServerProducerHint(Node node)
        {
            if (node == null)
                return null;

            return node.GetAttributeValue<string>("hint", CodeFluent.Producers.SqlServer.Constants.SqlServerProducerNamespaceUri, null);
        }
    } 
    ?>

</cf:project>

生成的表有聚集索引:

CREATE TABLE [dbo].[Course] (
    [Course_Id] [uniqueidentifier] NOT NULL,
    CONSTRAINT [PK_Cou_Cou_Cou] PRIMARY KEY CLUSTERED (...)
)
CREATE TABLE [dbo].[Student] (
    [Student_Id] [uniqueidentifier] NOT NULL,
    CONSTRAINT [PK_Stu_Stu_Stu] PRIMARY KEY CLUSTERED (...) 
)
CREATE TABLE [dbo].[Course_Students_Student_Courses] (
 [Course_Id] [uniqueidentifier] NOT NULL,
 [Student_Id] [uniqueidentifier] NOT NULL,
 CONSTRAINT [PK_Cor_Cou_Stu_Cor] PRIMARY KEY clustered(...)
)

编辑:要将聚集索引添加到预订实体,您必须设置cfps:clustered="true"

<cf:entity name="Booking" setType="List" trackingModes="None" namespace="Marmara">
  <cf:property name="Hotel" cfps:clustered="true" key="true" typeName="Marmara.Hotel" />
  <cf:property name="Fly" cfps:clustered="true" key="true" typeName="Marmara.Fly" />
  <cf:property name="Price" typeName="int" />
  <cf:property name="AvailableSeat" typeName="int" />
  <cf:property name="RunTimeDate" cfps:clustered="true" key="true" typeName="Marmara.RunTimeDate" />
</cf:entity>

这将生成以下 SQL 语句:

CREATE CLUSTERED INDEX [CL_dbo_Booking] ON [dbo].[Booking] ( [Booking_Hotel_ProductCode], [Booking_Fly_TakeOffDate], [Booking_RunTimeDate_Date]);
于 2016-02-15T11:03:46.187 回答