PK和FK不可能完成任務。問題在於沒有用於命名存儲約束的特殊EdmModel屬性/屬性/註釋 - 在模型中,它們基本上表示爲列(屬性)列表,命名約定在遷移生成器類中進行了硬編碼。請注意,評論中提到的一些示例顯示瞭如何重命名FK 列(屬性),而不是FK約束本身。
幸運的指標,但並不簡單,但很有可能,這要感謝IndexAttribute
和IndexAnnotation
。這是因爲註釋(帶有屬性)與列(實體屬性)相關聯,然後由名爲ConsolidatedIndex
的內部類進行合併。
因此,爲了實現這個目標,你必須創建IStoreModelConvention<EntityType>
,準備從類似ConsolidatedIndex
類是怎麼做的,要根據你的規則爲未命名的索引或索引使用默認名稱,新名稱的屬性綜合指數信息由ForeignKeyIndexConvention
爲FK約束生成,並更新屬性的相應IndexAnnotation
。
有了這樣說,這裏是將你的索引名慣例代碼:
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations.Schema;
using System.Data.Entity.Core.Metadata.Edm;
using System.Data.Entity.Infrastructure;
using System.Data.Entity.Infrastructure.Annotations;
using System.Data.Entity.Migrations.Model;
using System.Data.Entity.ModelConfiguration.Conventions;
using System.Linq;
public class IndexNameConvention : IStoreModelConvention<EntityType>
{
public void Apply(EntityType item, DbModel model)
{
// Build index info, consolidating indexes with the same name
var indexInfo = new List<IndexInfo>();
foreach (var p in item.Properties)
{
foreach (var mp in p.MetadataProperties)
{
var a = mp.Value as IndexAnnotation;
if (a == null) continue;
foreach (var index in a.Indexes)
{
var info = index.Name != null ? indexInfo.FirstOrDefault(e => e.Name == index.Name) : null;
if (info == null)
{
info = new IndexInfo { Name = index.Name };
indexInfo.Add(info);
}
else
{
var other = info.Entries[0].Index;
if (index.IsUnique != other.IsUnique || index.IsClustered != other.IsClustered)
throw new Exception("Invalid index configuration.");
}
info.Entries.Add(new IndexEntry { Column = p, Annotation = mp, Index = index });
}
}
}
if (indexInfo.Count == 0) return;
// Generate new name where needed
var entitySet = model.StoreModel.Container.EntitySets.First(es => es.ElementType == item);
foreach (var info in indexInfo)
{
var columns = info.Entries.OrderBy(e => e.Index.Order).Select(e => e.Column.Name);
if (info.Name == null || info.Name == IndexOperation.BuildDefaultName(columns))
{
bool unique = info.Entries[0].Index.IsUnique;
var name = string.Format("{0}_{1}_{2}", unique ? "UX" : "IX", entitySet.Table, string.Join("_", columns));
if (name.Length > 128) name = name.Substring(0, 128);
if (info.Name == name) continue;
foreach (var entry in info.Entries)
{
var index = new IndexAttribute(name);
if (entry.Index.Order >= 0)
index.Order = entry.Index.Order;
if (entry.Index.IsUniqueConfigured)
index.IsUnique = entry.Index.IsUnique;
if (entry.Index.IsClusteredConfigured)
index.IsClustered = entry.Index.IsClustered;
entry.Index = index;
entry.Modified = true;
}
}
}
// Apply the changes
foreach (var g in indexInfo.SelectMany(e => e.Entries).GroupBy(e => e.Annotation))
{
if (g.Any(e => e.Modified))
g.Key.Value = new IndexAnnotation(g.Select(e => e.Index));
}
}
class IndexInfo
{
public string Name;
public List<IndexEntry> Entries = new List<IndexEntry>();
}
class IndexEntry
{
public EdmProperty Column;
public MetadataProperty Annotation;
public IndexAttribute Index;
public bool Modified;
}
}
所有你需要的是在你的OnModelCreating
添加到DbModelBuilder.Conventions
:
modelBuilder.Conventions.Add<IndexNameConvention>();
HTTP:/ /stackoverflow.com/questions/22618237/how-to-create-index-in-entity-framework-6-2-with-code-first –
你可以在這裏看到:http://stackoverflow.com/a/18245172/ 5311735如何使用IStoreModelConvention修改外鍵名稱的示例。也許你可以用這種方式修改其他索引名稱。 – Evk
我試過但沒有成功。我也試過自定義的SQL生成器。但由於缺乏信息,我沒有任何結果 –