Misja niemożliwa dla PK i FK. Problem polega na tym, że nie ma żadnej specjalnej właściwości/atrybutu/adnotacji EdmModel do nazwania ograniczenia sklepu - w modelu są one zasadniczo reprezentowane jako lista kolumn (właściwości), a konwencja nazewnictwa jest zakodowana na stałe w klasach konstruktora migracji. Zwróć uwagę, że niektóre przykłady wspomniane w komentarzach pokazują, jak zmienić nazwę kolumn FK (właściwości), a nie samego ograniczenia FK.
Na szczęście dla indeksów, chociaż nie jest to proste, ale jest to możliwe, dzięki IndexAttribute
i IndexAnnotation
. Wynika to z faktu, że adnotacja (z atrybutem) jest powiązana z kolumną (właściwość encji), a następnie skonsolidowana przez wewnętrzną klasę o nazwie ConsolidatedIndex
.
Aby osiągnąć cel, musisz utworzyć IStoreModelConvention<EntityType>
, przygotować skonsolidowane informacje o indeksie z właściwości podobnych do tego, jak robi to klasa ConsolidatedIndex
, określić nową nazwę na podstawie reguł dla nienazwanych indeksów lub indeksów z domyślną nazwą wygenerowane dla ograniczeń FK przez ForeignKeyIndexConvention
i zaktualizować odpowiadające im właściwości o wartości IndexAnnotation
.
Mając to na uwadze powyższe, oto kod stosowania swoją nazwę indeksu konwencji:
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;
}
}
Wszystko, co potrzebne jest, aby dodać go do DbModelBuilder.Conventions
w swojej OnModelCreating
:
modelBuilder.Conventions.Add<IndexNameConvention>();
http://stackoverflow.com/questions/22618237/how-to-create-index-in-entity-framework-6-2-with-code-first –
Możesz zobaczyć tutaj: http://stackoverflow.com/a/18245172/ 5311735 przykład modyfikowania nazwy klucza obcego za pomocą IStoreModelConvention. Prawdopodobnie możesz w ten sposób modyfikować inne nazwy indeksów. – Evk
Próbowałem, ale bez powodzenia. Próbowałem również niestandardowego generatora sql. Ale z powodu braku informacji nie mam żadnych wyników. –