7

Tôi đang sử dụng Khuôn khổ thực thể 6.x bằng cách sử dụng phương pháp Tiếp cận mã đầu tiên trên ứng dụng MVC 5. Trong trường hợp đặc biệt này mô hình của tôi (trong số những thứ khác) chứa hai thuộc tính tên là Latitude và Longitude:Mã khuôn khổ thực thể Đầu tiên cắt bớt số thập phân của tôi

[Required, Range(-90, +90)] 
public decimal Latitude { get; set; } 

[Required, Range(-180, +180)] 
public decimal Longitude { get; set; } 

Và khi tôi thực hiện cuộc di cư Tôi có một cái gì đó như thế này

CreateTable("ResProperty"), c => new { 
     : 
    Latitude = c.Decimal(nullable: false, precision: 10, scale: 8), 
    Longitude = c.Decimal(nullable: false, precision: 11, scale: 8), 
     : 
}) 
... other stuff 

vì vậy cả hai vĩ độ và kinh độ có 8 số thập phân chữ số. Các cựu với 2 số nguyên (tối đa 90) và sau này với 3 số nguyên (tối đa 180).

Sau khi thực hiện cập nhật cơ sở dữ liệu-lệnh cột bảng của tôi được trình bày như sau:

Latitude decimal(10,8) 
Longitude decimal(11,8) 

mà dường như tốt với tôi. Bây giờ Theo quan điểm của tôi, tôi có một bản đồ và mã Javascript cho phép người dùng định vị lại điểm đánh dấu. Điều đó cũng tốt. Khi điểm đánh dấu được định vị lại, các trường Vĩ độ và Kinh độ được điền bằng giá trị được cập nhật (Javascript) có nhiều hơn 12 chữ số thập phân. Điều đó không quan trọng AFAIK vì quy mô của tôi là 8 số thập phân.

Sau khi nhấn nút gửi và phương thức tạo hoặc chỉnh sửa POST tôi kiểm tra thể hiện mô hình và tôi xác nhận rằng giá trị thực được truyền trong mô hình cho bộ điều khiển là chính xác, chúng có nhiều chữ số thập phân (những nơi có mã Javascript). Vì vậy, giá trị là chính xác.

Bây giờ ... vấn đề là sau khi db.SaveChanges() được thực hiện cơ sở dữ liệu được cập nhật - và tôi đã xác nhận rằng ghi/cập nhật thực tế đã diễn ra - nhưng bằng cách nào đó, EF bỏ qua các giá trị thực tế của tôi và ghi vĩ độ/kinh độ cắt ngắn được làm tròn thành HAI chữ số thập phân CHỈ, vì vậy Latitude của tôi hiển thị trong DB là 09.500000000 tất cả các chữ số thập phân khác được đánh số không bởi vì làm tròn dường như đã diễn ra.

// Prior to SaveChanges() 
Latitude = 9.08521879 
Longitude = -79.51658792 
// After SaveChanges() 
Latitude = 9.08000000 
Longitude = -79.51000000 

Tại sao nó làm tròn nó nếu tôi đã đưa ra chính xác tỷ lệ và độ chính xác và cột cũng có quy mô và độ chính xác chính xác? tại sao SaveChanges thay đổi giá trị của tôi? Tôi đã tìm thấy bài đăng này (http://weiding331.blogspot.com/2014/01/entity-framework-decimal-value.html) là vấn đề tương tự nhưng tôi không biết làm thế nào tôi có thể sửa lỗi đó (nếu có) vì tôi đã thực hiện một số di chuyển và bổ sung dữ liệu sau khi bảng được đề cập là "đã di chuyển ".

Tóm tắt

  • Các loại mô hình dữ liệu là chính xác (thập phân)
  • Mã cơ sở dữ liệu di cư có đúng precion/quy mô (lat 10/8 lon 11/8)
  • Các cột cơ sở dữ liệu SQL có độ chính xác/thang đo (lat 10/8, long 11/8)
  • Các giá trị được truyền trong mô hình có ít nhất 8 chữ số thập phân cho cả vĩ độ và kinh độ
  • ghi/cập nhật thực tế giá trị ce trong cơ sở dữ liệu không có lỗi, nhưng ...
  • Các giá trị ghi trên cơ sở dữ liệu cho hai cột này được cắt ngắn đến hai chữ số thập phân và hiển thị các chữ số thập phân quan trọng nhất khác như zero (0)
+0

Bạn có thể chỉ định quy mô và độ chính xác trong mô hình của bạn? Hãy xem câu hỏi này http://stackoverflow.com/questions/3504660/decimal-precision-and-scale-in-ef-code-first? Trên một lưu ý khác, EF không hỗ trợ kiểu dữ liệu không gian ... – Pawel

+0

Tôi không nghĩ rằng mình có thể sử dụng OnModelCreating nữa vì việc di chuyển cụ thể đó là một số cấp trong danh sách di chuyển của tôi. Tôi đã thêm nó vào mortem và chạy Update-Database (không có bất kỳ di chuyển mới nào) nhưng không thấy nó giải quyết được vấn đề. Bên cạnh các cột SQL trên DB đã cho thấy độ chính xác chính xác nhưng EF đã cắt ngắn nó trong nội bộ trong SaveChanges(). –

Trả lời

6

EF có một tài sản đặc biệt cho SqlProviderServices (thực hiện cho nhà cung cấp SqlClient cho SQL Server) - TruncateDecimalsToScale. Giá trị mặc định là đúng vì vậy có thể bạn có thể thay đổi giá trị thành giá trị sai. Ví dụ:

thông tin
public class DbContextConfiguration : DbConfiguration 
    { 
     public DbContextConfiguration() 
     { 
      var now = SqlProviderServices.Instance; 
      SqlProviderServices.TruncateDecimalsToScale = false; 
      this.SetProviderServices(SqlProviderServices.ProviderInvariantName, SqlProviderServices.Instance); 
     } 
    } 

    [DbConfigurationType(typeof(DbContextConfiguration))] 
    public class MyContext : DbContext 
    { ... } 

Thông tin thêm về rằng: https://msdn.microsoft.com/en-us/library/system.data.entity.sqlserver.sqlproviderservices.truncatedecimalstoscale%28v=vs.113%29.aspx

+0

Điều này giống như chính xác những gì tôi đang tìm kiếm nhưng bạn có thể giải thích cách giá trị được đặt ở đây không? Có một biến "bây giờ" mà dường như không được sử dụng và thuộc tính dường như được đặt trên một phương thức tĩnh. Đây có phải là cách tốt nhất để thiết lập giá trị này không? Tôi ngạc nhiên rằng một tính năng quan trọng như vậy không có thêm tài liệu xung quanh nó - cắt ngắn số thập phân chắc chắn là một vấn đề lớn. Cảm ơn. – Mark007

+0

@ Mark007 là một cấu hình toàn cầu. Tất nhiên cũng không phải là một nơi tốt để thiết lập những thứ này nhưng bạn biết đó là EF;) –

+0

Nó hoạt động và giải quyết vấn đề nhưng tôi nghĩ tôi cần những thứ ILSpy và xem chính xác những gì đang xảy ra tại một số điểm. – Mark007

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