2012-05-10 46 views
14

The specified cast from a materialized 'System.Guid' type to the 'System.Int32' type is not valid.Dàn diễn viên xác định từ một 'System.Guid' loại cụ thể hóa đến 'System.Int32' loại là không hợp lệ

Chúng ta có nhiều dịch vụ WCF có chế độ đồng thời của Nhiều và InstanceContextMode của đơn. Kiến trúc của chúng tôi tập trung vào một mô hình kết hợp lỏng lẻo bằng cách sử dụng tiêm phụ thuộc dựa trên hàm tạo. Điều này lần lượt được thực hiện bằng cách sử dụng Unity 2.0 (web.config của mỗi dịch vụ có ánh xạ giữa các giao diện và các loại được định nghĩa trong một phần container thống nhất). Một trong những phụ thuộc của chúng ta là một assembly DAL (lớp truy cập dữ liệu) sử dụng Entity Framework 4 để giao tiếp với MSSql Server. Các lớp làm việc nói chuyện với cơ sở dữ liệu cũng được bao gồm trong ánh xạ thống nhất.

Mọi thứ đều tuyệt vời khi chúng tôi chạy thử nghiệm tích hợp của mình. Nhưng khi chúng ta chuyển sang môi trường hoạt động của chúng tôi để chạy thử nghiệm tải (2, 3, 4 người dùng đồng thời), chúng tôi bắt đầu thấy các lỗi sau:

System.InvalidOperationException: The 'auth_token' property on 'Session' could not be set to a 'Int32' value. You must set this property to a non-null value of type 'Guid'.

Với stack sau:

at System.Data.Common.Internal.Materialization.Shaper.ErrorHandlingValueReader`1.GetValue(DbDataReader reader, Int32 ordinal) 
at System.Data.Common.Internal.Materialization.Shaper.GetPropertyValueWithErrorHandling[TProperty](Int32 ordinal, String propertyName, String typeName) 
at lambda_method(Closure , Shaper) 
at System.Data.Common.Internal.Materialization.Shaper.HandleEntityAppendOnly[TEntity](Func`2 constructEntityDelegate, EntityKey entityKey, EntitySet entitySet) 
at lambda_method(Closure , Shaper) 
at System.Data.Common.Internal.Materialization.Coordinator`1.ReadNextElement(Shaper shaper) 
at System.Data.Common.Internal.Materialization.Shaper`1.SimpleEnumerator.MoveNext() 
at System.Linq.Enumerable.First[TSource](IEnumerable`1 source) 
at System.Linq.Queryable.First[TSource](IQueryable`1 source) 
at MISoa.DataAccessLayer.Authentication.AuthenticationDB.RetrieveSession(Guid authToken) 
at MISoa.DataAccessLayer.Authentication.AuthenticationAccess.RetrieveSession(String sessionToken) 

đây là phương pháp thủ phạm:

public Session RetrieveSession(Guid authToken) 
    { 
     CheckDBContext(); 
     var sessions = (from r in _dbContext.Sessions 
       where r.auth_token == authToken 
       select r); 
     return sessions.Count() > 0 ? sessions.First() : null; 
    } 

CheckDBContext phương pháp đơn giản là kiểm tra nếu bối cảnh db là null và, nếu có, nó ném một tùy chỉnh excep sự.

Các đối tượng Session thực thể emdx có những tính chất công cộng:

Guid auth_token 
DateTime time_stamp 
String user_id 
String app_id 

Vì vậy, có vẻ như đôi khi LINQ trên trả về một số đối tượng khác từ cơ sở dữ liệu mà cột đầu tiên là một int và không phải là một guid? Và nếu có - tại sao? Tôi có gặp vấn đề với nhiều luồng ghi đè ngữ cảnh db của nhau không? BTW - chúng tôi tóm tắt mã mà instantiates bối cảnh db đến một lớp riêng biệt (BaseDB) mà cũng được xử lý bởi sự thống nhất. Vì vậy, bởi vì dịch vụ là một singleton, tôi có một ví dụ của BaseDB cho tất cả mọi người, phải không? Đây có phải là vấn đề ở đây không?

Ồ, một điều nữa. Chúng tôi đã nói rằng chúng tôi sẽ có MSSql 2005 vì vậy trong tập tin edmx chúng tôi có ProviderManifestToken="2005". Nhưng tôi vừa kiểm tra và máy chủ với cơ sở dữ liệu hiệu suất của chúng tôi là phiên bản 2008. Đây có phải là vấn đề không?

Cảm ơn sự giúp đỡ của bạn.

+0

Những điều đơn giản đầu tiên tôi muốn kiểm tra: là auth_token một hướng dẫn trong db của bạn? Lỗi cho biết có điều gì đó đang cố đặt session.auth_token thành int. Có một cột Id int không được ánh xạ đúng không?Bạn có thể làm một dấu vết profiling sql và xác định các cuộc gọi sql thực tế được thực hiện? Tôi thực sự nghi ngờ rằng đa luồng đang gây ra vấn đề của bạn ở đây. –

+0

Bạn có chắc chắn rằng cột trong cơ sở dữ liệu thuộc loại thuộc tính tương ứng không? Ngoại lệ nói rằng DbDataReader đọc Guid nhưng thuộc tính trên lớp của bạn là int. – Pawel

Trả lời

2

Do I have a problem with multiple threads overriding each other's db context?

Có. Xem ở đây: http://msdn.microsoft.com/en-us/library/system.data.objects.objectcontext.aspx

Trích từ hộp vàng lớn trong liên kết ở trên:

The ObjectContext class is not thread safe. The integrity of data objects in an ObjectContext cannot be ensured in multithreaded scenarios.

Bạn có thể muốn xem xét việc đặt [ThreadStaticAttribute] trên sân _dbContext của bạn.

+1

Vì vậy, vấn đề chính là ObjectContext không phải là Threadsafe - thats ok, nhưng tôi chỉ muốn đề cập rằng làm cho tài sản DbContext Threadstatic có thể gây ra nhiều vấn đề hơn khi được sử dụng trong WCF/Asp.Net, tùy thuộc vào Host và cách (hoặc tốt hơn khi) bạn khởi tạo thuộc tính. Ví dụ khi sử dụng WCF, bạn nên sử dụng OperationContext để lưu trữ những thứ này, vì Thread đang chấp nhận Yêu cầu có thể không phải là cùng một Thread đang thực thi nó. xem [operationcontext] (http://msdn.microsoft.com/en-us/library/system.servicemodel.operationcontext.aspx). –

+0

@Bernhard Kircher: khá đúng - điểm tốt! – RobSiklos

0

Tôi nghi ngờ vấn đề của bạn phát sinh khi không có kết quả và giá trị null == 0 được sử dụng để so sánh trường Guid ở đâu đó trong SQL được tạo. Hãy thử thực hiện so sánh dưới dạng một chuỗi (.ToString() trên cả hai) và xem bạn có thể bắt được trường hợp đang gây ra sự cố hay không.

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