2017-02-12 15 views
5

Cách tạo chỉ mục tùy chỉnh và quy ước chính cho các loại chỉ mục khác nhau. Tôi cần đặt tên khác nhau cho sau loại chìa khóa hoặc chỉ số:Quy ước chỉ mục duy nhất trong EF6

  • PK_TableName Khóa chính
  • FK_SourceTable_Column_TargetTable cho các phím nước ngoài
  • IX_TableName_Column1_Column2 chỉ số không duy nhất
  • UX_TableName_Column1_Column2 chỉ số Unique

Bởi mặc định, Entity Framework sử dụng namings sau:

  • PK_ schemaname .TableName cho khóa chính
  • FK_ schemaname .SourceTable_ schemaname .TargetTable_Column1 cho các phím nước ngoài
  • IX_Column1 cho các chỉ mục không phải duy nhất
  • ColumnName cho chỉ số độc đáo

Tôi đã phát hiện ra rằng tôi có thể thực hiện IStoreModelConvention<T>, nhưng tôi đã không tìm thấy loại hình cụ thể để sử dụng như tham số kiểu. Hơn nữa, có thể là Custom Code-First Conventions, nhưng nghiên cứu của tôi đã kết thúc mà không có kết quả. Làm cách nào tôi có thể nhận các quy tắc đặt tên được đề cập khi tôi sử dụng Khung thực thể Mã số đầu tiên? Nó có thể là bất cứ điều gì: gói, mẫu, hoặc chỉ hướng cho các nghiên cứu sau đây.

+0

http://stackoverflow.com/questions/22618237/how-to-create-index-in-entity-framework-6-2-with-code-first –

+0

Bạn có thể xem tại đây: http://stackoverflow.com/a/18245172/ 5311735 ví dụ về cách sửa đổi tên khóa ngoài bằng cách sử dụng IStoreModelConvention. Có lẽ bạn có thể sửa đổi các tên chỉ mục khác theo cách này. – Evk

+0

Tôi đã thử nhưng không thành công. Tôi cũng đã thử máy phát điện sql tùy chỉnh. Nhưng do thiếu thông tin tôi không có bất kỳ kết quả nào –

Trả lời

4

Nhiệm vụ không thể cho PK và FK. Vấn đề là không có thuộc tính/thuộc tính/chú thích đặc biệt của EdmModel để đặt tên cho ràng buộc cửa hàng - trong mô hình chúng được trình bày cơ bản dưới dạng danh sách các cột (thuộc tính) và quy ước đặt tên được mã hóa cứng bên trong các lớp trình xây dựng di trú. Xin lưu ý rằng một số ví dụ được đề cập trong các ý kiến ​​được hiển thị như thế nào để đổi tên các cột FK (thuộc tính), không phải bản thân ràng buộc FK.

May mắn cho các chỉ mục, mặc dù không đơn giản, nhưng có thể nhờ vào số IndexAttributeIndexAnnotation. Điều này là do chú thích (có thuộc tính) được liên kết với cột (thuộc tính thực thể) và sau đó được hợp nhất bởi một lớp nội bộ có tên là ConsolidatedIndex. Vì vậy, để đạt được mục tiêu, bạn phải tạo IStoreModelConvention<EntityType>, chuẩn bị thông tin chỉ mục tổng hợp từ các thuộc tính tương tự như cách ConsolidatedIndex thực hiện, xác định tên mới dựa trên các quy tắc của bạn cho các chỉ mục hoặc chỉ mục chưa được đặt tên với tên mặc định được tạo cho các ràng buộc FK theo số ForeignKeyIndexConvention và cập nhật các thuộc tính tương ứng IndexAnnotation.

Với điều đó đang được nói, đây là mã để áp dụng tên chỉ số ước của bạn:

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; 
    } 
} 

Tất cả bạn cần là thêm nó vào DbModelBuilder.Conventions trong bạn OnModelCreating:

modelBuilder.Conventions.Add<IndexNameConvention>(); 
+1

Boy! Điều này phải có rất nhiều kiên nhẫn! –

+0

@GertArnold Thật ra khó khăn hơn nhiều với tôi để soạn một câu trả lời hơn là khám phá nguồn EF và viết mã :) –

+0

@IvanStoev Tôi cũng đã cố gắng vượt qua các nguồn, nhưng nó khá khó khăn ... –

Các vấn đề liên quan