繁体   English   中英

带索引的实体框架代码生成

[英]Entity Framework Code Generation with Indexes

有没有办法告诉.NET 4 ADO.NET实体的SQL生成器为特定列创建索引?

指数本身不支持,但是如果你的头的“影响的DDL生成”一节这个文章中,你可以看到这个自定义功能添加到现有的模板。

在本文的示例中,EDMX的CSDL中的新索引如下所示:

<Property ... >
  <myExtensions:Index indexName="Seat" edmx:CopyToSSDL="true"/>
</Property>

但是要使此工作正常,您必须修改一些内容(有关详细信息,请参见我提供的链接)。 首先,您必须在架构节点上声明“ myExtensions”命名空间:

<!-- CSDL content -->
<edmx:ConceptualModels>
  <Schema [...] xmlns:myExtensions="http://www.microsoft.com/userExtensions">
  [...]
</edmx>

其次,您必须修改位于以下位置的模板:

\\ Microsoft Visual Studio 10.0 \\ Common7 \\ IDE \\ Extensions \\ Microsoft \\ Entity Framework Tools \\ DBGen \\ SSDLToSQL10.tt

该解决方案需要Linq,因此请将其添加到模板顶部:

<#@ assembly name="System.Xml.Linq" #>

然后将其添加到底部:

-- Creating index for table based on custom extensions --
<#
   foreach (EntitySet entitySet in Store.GetAllEntitySets())
   {
     string tableName = Id(entitySet.GetTableName());
     string schemaName = Id(entitySet.GetSchemaName());
     EdmProperties props = entitySet.ElementType.Properties;
     foreach (EdmProperty ep in props.Where(p =>
                           p.TypeUsage.EdmType is PrimitiveType))
     {
        MetadataProperty meta = ep.MetadataProperties.FirstOrDefault(mp => mp.Name == "http://www.microsoft.com/userExtensions:Index");
        if (meta != null)
        {
            System.Xml.Linq.XElement e = meta.Value as System.Xml.Linq.XElement;
            System.Xml.Linq.XAttribute attr = e.Attributes().FirstOrDefault(a => a.Name == "indexName");
            string indexName = attr.Value;     
            // create an index for specified column
#>
CREATE INDEX [IX_<#=indexName#>]
ON <#if (!IsSQLCE) {#>[<#=schemaName#>].<#}#>[<#=tableName#>]
([<#=indexName#>]);
<#
         }
     }   
   }
#>

其中大多数可以很容易地修改以满足您的需求。 本文将介绍更多细节,但是以上代码中最重要的一行是获取自定义“ Index”扩展节点的那一行:

MetadataProperty meta = ep.MetadataProperties.FirstOrDefault(mp => mp.Name == "http://www.microsoft.com/userExtensions:Index");

希望有帮助!

为了补充Smudge的回答,需要做一些技巧才能使它在EF 5中起作用。

例如,edmx:CopyToSSDL =“ true”不能立即使用。 您必须进行一些修改:

<Schema xmlns="http://schemas.microsoft.com/ado/2009/11/edm" xmlns:cg="http://schemas.microsoft.com/ado/2006/04/codegeneration"
              xmlns:store="http://schemas.microsoft.com/ado/2007/12/edm/EntityStoreSchemaGenerator" Namespace="CPEData" Alias="Self"
              xmlns:annotation="http://schemas.microsoft.com/ado/2009/02/edm/annotation" annotation:UseStrongSpatialTypes="false"
              xmlns:myExtensions="http://www.microsoft.com/userExtensions"
              xmlns:edmxv2="http://schemas.microsoft.com/ado/2008/10/edmx" >

然后在自定义属性中(注意edmxv2):

<myExtensions:Index edmxv2:CopyToSSDL="true" IndexName="Name" Columns="Name" >

有关更多信息,请参见此链接

另外,我确实更改了一些T4代码以使其更容易。 我以该示例为基础,以实现更灵活的自定义元素语法。

例如,您可以在EntityType元素的末尾添加一个自定义元素(不必将其放在<Property></Property>标记内):

<myExtensions:Index edmxv2:CopyToSSDL="true" IndexName="Name" Columns="Name" >
    Custom metadata (not needed)
</myExtensions:Index>

然后修改.tt模板:

-- --------------------------------------------------
-- Creating all Indexes based on custom extensions   
-- --------------------------------------------------

<#
   foreach (EntitySet entitySet in Store.GetAllEntitySets())
   {
     string tableName = Id(entitySet.GetTableName());
     string schemaName = Id(entitySet.GetSchemaName());
     var props = entitySet.ElementType.MetadataProperties.Where(p => p.Name == "http://www.microsoft.com/userExtensions:Index");
     foreach (MetadataProperty meta in props)
     {
        System.Xml.Linq.XElement e = meta.Value as System.Xml.Linq.XElement;
        string indexName = e.Attributes().FirstOrDefault(a => a.Name == "IndexName").Value;
        string columnsName = e.Attributes().FirstOrDefault(a => a.Name == "Columns").Value;
        // create an index for specified column
#>
CREATE INDEX [IX_<#=indexName#>]
ON <#if (!IsSQLCE) {#>[<#=schemaName#>].<#}#>[<#=tableName#>]
([<#=columnsName#>]);
<#

     }   
   }
#>

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM