2017-01-04 20 views
8

Ứng dụng khách của tôi có tiêu chuẩn lưu trữ số thập phân SQL Server với thông số thập phân (13,4). Kết quả là, trong một sơ đồ rất lớn và vẫn đang phát triển, tôi có gần một trăm câu như thế này:Lặp/phản ánh qua tất cả các thuộc tính trong tất cả các Mô hình EF để đặt Loại Cột

builder.Entity<MyObject>() 
    .Property(x => x.MyField1) 
    .ForSqlServerHasColumnType("decimal(13,4)"); 
builder.Entity<MyObject>() 
    .Property(x => x.MyField2) 
    .ForSqlServerHasColumnType("decimal(13,4)"); 
builder.Entity<MyObject2>() 
    .Property(x => x.MyField1) 
    .ForSqlServerHasColumnType("decimal(13,4)"); 

Nếu có một tính năng mà tôi có thể nói EF trực tiếp rằng tất cả các số thập phân nên số thập phân (13, 4) theo mặc định, tôi muốn sử dụng điều đó. Nếu không, tôi có thể sử dụng sự phản chiếu để lặp qua mọi đối tượng/thuộc tính trong mô hình để tôi có thể làm điều này trong một vài câu lệnh không?

Cái gì như:

foreach(var efObj in EntityFrameWorkObjects) 
{ 
    foreach (var objProperty in efObj) 
    { 
     if (objProperty is decimal || objProperty is decimal?) 
     { 
      builder.Entity<efObj>() 
       .Property(x => x.efObj) 
       .ForSqlServerHasColumnType("decimal(13,4)"); 
     } 
    } 
} 

Reflection có vẻ như là một cách tuyệt vời để đi, bởi vì sau đó tôi có thể thực hiện một số công ước khác của chúng tôi ở đâu, nếu một đối tượng có một tên và mô tả, tên được yêu cầu và giới hạn tới 256 ký tự.

Cập nhật: Tôi làm theo các liên kết trong comment của Ivan và thích nghi nó vào đó, mà làm việc cho tôi:

foreach (var p in builder.Model 
    .GetEntityTypes() 
    .SelectMany(t => t.GetProperties()) 
    .Where(p => 
     p.ClrType == typeof(decimal) || 
     p.ClrType == typeof(decimal?))) 
{ 
    p.SqlServer().ColumnType = "decimal(13,4)"; 
} 

Ngay sau đó, ông cung cấp một câu trả lời đầy đủ, mà tôi đã thay đổi một chút để làm việc với cả số thập phân thập phân và số thập phân có thể null:

foreach (var pb in builder.Model 
    .GetEntityTypes() 
    .SelectMany(t => t.GetProperties()) 
    .Where(p => 
     p.ClrType == typeof(decimal) || 
     p.ClrType == typeof(decimal?)) 
    .Select(p => 
     builder.Entity(p.DeclaringEntityType.ClrType) 
      .Property(p.Name))) 
{ 
    pb.ForSqlServerHasColumnType("decimal(13,4)"); 
} 

Cả hai cách tiếp cận đều hoạt động!

Cập nhật 2: Tôi phải có đối tượng được khai báo là DbSet <> trong ngữ cảnh để làm việc ở trên. Điều này dường như không được yêu cầu khi tôi thiết lập các thuộc tính theo từng dòng.

+1

Xem [thay đổi tất cả chiều dài chuỗi tối đa tài sản] (http://stackoverflow.com/questions/41427030/change-all-string -property-max-length/41427828 # 41427828) cho một cái gì đó tương tự trong v1.1.0 (không thể kiểm tra trong v.1.0) –

+1

Về Cập Nhật 2: Mã nên ở phần cuối của 'OnModelCreating' sau khi tất cả các loại thực thể được phát hiện, do đó bao gồm các kiểu không phải là DbSet', được giới thiệu ví dụ với các cuộc gọi 'modelBuilder.Entity <..>'. –

+0

@IvanStoev có ý nghĩa, nhưng tôi có một số câu lệnh 'modelBuilder.Entity <..>' trong đó chỉ để xác định loại cột thập phân, vì vậy các câu lệnh đó biến mất ngay bây giờ. – Chris

Trả lời

18

Trong EF Lõi v1.1.0 bạn có thể sử dụng một cái gì đó như thế này:

foreach (var pb in modelBuilder.Model 
    .GetEntityTypes() 
    .SelectMany(t => t.GetProperties()) 
    .Where(p => p.ClrType == typeof(decimal)) 
    .Select(p => modelBuilder.Entity(p.DeclaringEntityType.ClrType).Property(p.Name))) 
{ 
    pb.ForSqlServerHasColumnType("decimal(13,4)"); 
} 
+2

Điều này đã thay đổi một chút, ít nhất là đối với lõi ef 2.0. Thay vì ForSqlServer, bạn cần sử dụng nuget Microsoft.EntityFrameworkCore.SqlServer. Phần mở rộng được đặt tên là HasColumnType. – Joshit

+0

pb.HasColumnType ("thập phân (13,4)"); sẽ là đúng nếu một người sử dụng SqlServer – Joshit

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