Có cách nào để tạo chỉ mục trên thuộc tính / cột bằng cách sử dụng mã đầu tiên, thay vì sử dụng mới IndexAttribute
không?
Có cách nào để tạo chỉ mục trên thuộc tính / cột bằng cách sử dụng mã đầu tiên, thay vì sử dụng mới IndexAttribute
không?
Câu trả lời:
Ngày 26 tháng 10 năm 2017 Entity Framework 6.2 chính thức được phát hành . Nó bao gồm khả năng xác định các chỉ mục một cách dễ dàng thông qua API Fluent. Ho mà nó sẽ sử dụng đã được công bố trong bản beta của 6.2.
Bây giờ bạn có thể sử dụng HasIndex()
phương thức này, tiếp theo là IsUnique()
nếu nó phải là một chỉ mục duy nhất.
Chỉ là một ví dụ so sánh nhỏ (trước / sau):
// before
modelBuilder.Entity<Person>()
.Property(e => e.Name)
.HasColumnAnnotation(
IndexAnnotation.AnnotationName,
new IndexAnnotation(new IndexAttribute { IsUnique = true }));
// after
modelBuilder.Entity<Person>()
.HasIndex(p => p.Name)
.IsUnique();
// multi column index
modelBuilder.Entity<Person>()
.HasIndex(p => new { p.Name, p.Firstname })
.IsUnique();
Cũng có thể đánh dấu chỉ mục là được nhóm với .IsClustered()
.
CHỈNH SỬA # 1
Đã thêm một ví dụ về chỉ mục nhiều cột và thông tin bổ sung về cách đánh dấu một chỉ mục là được nhóm.
CHỈNH SỬA # 2
Như thông tin bổ sung, trong EF Core 2.1 nó giống hệt như trong EF 6.2 bây giờ.
Đây là tài liệu tham khảo về MS Doc.
new
. Tôi sẽ sửa nó.
Hiện tại không có "hỗ trợ hạng nhất" để tạo chỉ mục thông qua API thông thạo, nhưng những gì bạn có thể làm là thông qua API thông thạo, bạn có thể đánh dấu thuộc tính là có thuộc tính từ API chú thích. Điều này sẽ cho phép bạn thêm Index
thuộc tính thông qua một giao diện thông thạo.
Dưới đây là một số ví dụ từ hạng mục công việc từ trang Sự cố cho EF.
Tạo chỉ mục trên một cột duy nhất:
modelBuilder.Entity<MyEntity>()
.Property(e => e.MyProperty)
.HasColumnAnnotation(
IndexAnnotation.AnnotationName,
new IndexAnnotation(new IndexAttribute()));
Nhiều chỉ mục trên một cột:
modelBuilder.Entity<MyEntity>()
.Property(e => e.MyProperty)
.HasColumnAnnotation(
IndexAnnotation.AnnotationName,
new IndexAnnotation(new[]
{
new IndexAttribute("Index1"),
new IndexAttribute("Index2") { IsUnique = true }
}));
Chỉ mục nhiều cột:
modelBuilder.Entity<MyEntity>()
.Property(e => e.MyProperty1)
.HasColumnAnnotation(
IndexAnnotation.AnnotationName,
new IndexAnnotation(new IndexAttribute("MyIndex", 1)));
modelBuilder.Entity<MyEntity>()
.Property(e => e.MyProperty2)
.HasColumnAnnotation(
IndexAnnotation.AnnotationName,
new IndexAnnotation(new IndexAttribute("MyIndex", 2)));
Sử dụng các kỹ thuật trên sẽ làm cho .CreateIndex()
các lệnh gọi được tạo tự động cho bạn trong Up()
hàm của bạn khi bạn mở đầu lần di chuyển tiếp theo (hoặc được tạo tự động trong cơ sở dữ liệu nếu bạn không sử dụng di chuyển).
.Primarykey(x=>x.id,clustered:false)
phương pháp
HasAnnotation
phương pháp và KHÔNG có phương pháp nào như thế này. nhưng tôi đã tìm thấy một phương thức có tên HasColumnAnnotation
chấp nhận các tham số mà bạn cung cấp. Bạn cần cập nhật câu trả lời của mình hay tôi nhầm?
Tôi đã tạo một số phương thức mở rộng và gói chúng trong một gói nuget để làm cho việc này dễ dàng hơn nhiều.
Cài đặt EntityFramework.IndexingExtensions
gói nuget.
Sau đó, bạn có thể làm như sau:
public class MyDataContext : DbContext
{
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Customer>()
.HasIndex("IX_Customers_Name", // Provide the index name.
e => e.Property(x => x.LastName), // Specify at least one column.
e => e.Property(x => x.FirstName)) // Multiple columns as desired.
.HasIndex("IX_Customers_EmailAddress", // Supports fluent chaining for more indexes.
IndexOptions.Unique, // Supports flags for unique and clustered.
e => e.Property(x => x.EmailAddress));
}
}
Dự án và mã nguồn ở đây . Thưởng thức!
IndexAttribute
lớp học của EF tiết lộ , vì vậy tôi không thể đưa nó vào thư viện của mình.
Không có tên rõ ràng:
[Index]
public int Rating { get; set; }
Với một tên cụ thể:
[Index("PostRatingIndex")]
public int Rating { get; set; }
EntityFramework
. nó được bao gồm trong lắp ráp đó. chỉ nhầm lẫn về NS.
instead of using the new IndexAttribute
bạn có nhận thấy nó không?
Từ EF 6.1 trở đi, thuộc tính [Index]
được hỗ trợ.
Sử dụng [Index(IsUnique = true)]
cho chỉ mục duy nhất.
Đây là liên kết từ Microsoft
public class User
{
public int UserId { get; set; }
[Index(IsUnique = true)]
[StringLength(200)]
public string Username { get; set; }
public string DisplayName { get; set; }
}
[Index("IX_BlogIdAndRating", 2)]
public int Rating { get; set; }
[Index("IX_BlogIdAndRating", 1)]
public int BlogId { get; set; }
Đây là tài liệu tham khảo từ Microsoft
Khung thực thể 6
Property(c => c.MyColumn)
.HasColumnAnnotation("Index", new IndexAnnotation(new IndexAttribute("IX_MyIndex")));
Và thêm bằng cách sử dụng:
using System.Data.Entity.Infrastructure.Annotations;
using System.ComponentModel.DataAnnotations.Schema;
Bạn có thể sử dụng chú thích dữ liệu INDEX Mã chú thích dữ liệu đầu tiên
Nếu bạn không muốn sử dụng các thuộc tính trên POCO của mình, thì bạn luôn có thể làm như sau:
context.Database.ExecuteSqlCommand("CREATE INDEX IX_NAME ON ...");
Bạn có thể thực thi câu lệnh này trong DbInitializer
lớp dẫn xuất tùy chỉnh của mình . Tôi không biết bất kỳ cách nào của Fluent API để thực hiện việc này.
Tôi viết một phương thức mở rộng để sử dụng trong EF thông thạo để tránh thêm mã:
public static PrimitivePropertyConfiguration HasIndexAnnotation(
this PrimitivePropertyConfiguration primitivePropertyConfiguration,
IndexAttribute indexAttribute = null
)
{
indexAttribute = indexAttribute ?? new IndexAttribute();
return primitivePropertyConfiguration
.HasColumnAnnotation(
IndexAnnotation.AnnotationName,
new IndexAnnotation(indexAttribute)
);
}
sau đó sử dụng nó như thế này:
Property(t => t.CardNo)
.HasIndexAnnotation();
hoặc như thế này nếu chỉ mục cần một số cấu hình:
Property(t => t.CardNo)
.HasIndexAnnotation(new IndexAttribute("IX_Account") { IsUnique = true });
Bạn có thể sử dụng một trong số này
// Chỉ mục
this.HasIndex(e => e.IsActive)
.HasName("IX_IsActive");
hoặc là
this.Property(e => e.IsActive).HasColumnAnnotation(
"Index",
new IndexAnnotation(new IndexAttribute("IX_IsActive")));