[英]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.