使用SQL Server生成器

时间:2016-02-14 14:46:09

标签: sql-server codefluent

我遇到与此问题相同的问题(完全相同的需求):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" />

1 个答案:

答案 0 :(得分: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]);