6

Bối cảnh:Sử dụng tính chất định hướng trong mã khuôn khổ thực thể đầu tiên

  • Mã Thứ nhất, Entity Framework 4.3.1;
  • Người dùng ---- Chủ đề, 1 đến nhiều quan hệ;
  • User với public virtual ICollection<Topic> CreatedTopics Thuộc tính điều hướng (Tải gấp);
  • Topic với public virtual User Creator Thuộc tính điều hướng;
  • DataServiceController : DbDataController<DefaultDbContext>, Web API beta, ASP.NET MVC 4 Beta, Ứng dụng một trang;
  • System.Json để tuần tự hóa Json;
  • Web Action API:

    public IQueryable<Topic> GetTopics() 
    { 
        // return DbContext.Topics;     // OK 
        return DbContext.Topics.Include("Creator"); //With Exception 
    } 
    
  • Kết quả: "một unhandled microsoft net framework ngoại lệ xảy ra trong w3wp.exe"

Vấn đề ở đây có vẻ là: Tôi nên không Thêm Thuộc tính Điều hướng trong cả hai Thực thể (Nguyên nhân Tham chiếu Thông tư?) và nếu tôi xóa CreatedTopics Thuộc tính Điều hướng trong User Lớp học, Nó sẽ được OK một lần nữa.

Vì vậy, Trong một bối cảnh tương tự như liệt kê ở trên, Dưới đây là những câu hỏi của tôi:

  1. Làm thế nào để đối phó với Navigation Properties trong tình hình 1 tới Nhiều liên quan;
  2. Hơn nữa, làm thế nào về một Nhiều đến nhiều quan hệ, tôi có phải chia nó thành hai mối quan hệ 1 đến nhiều;
  3. Thực tiễn tốt nhất và biện pháp phòng ngừa khi sử dụng Thuộc tính điều hướng là gì?

Tôi đã đọc nhiều bài viết có liên quan, nhưng vẫn không đủ rõ ràng :(,

Nhờ sự giúp đỡ

Dean

Trả lời

9

Đây không phải là một vấn đề về mã đầu tiên hoặc EF - Đơn giản là serializer được sử dụng để chuyển đổi đồ thị đối tượng của bạn thành một số biểu diễn được truyền trong thông báo Web API không thể làm việc với tham chiếu vòng tròn theo mặc định. theo mặc định - here là một bout serializers mặc định được sử dụng bởi Web API và về cách thay đổi nó. Các văn bản sau giả sử rằng bạn đang sử dụng DataContractJsonSerializer hoặc DataContractSerializer (nên được mặc định cho xê-ri hóa XML) nhưng cũng có thể cho JSON.NET (nên mặc định cho JSON serialization - JSON serialization có thể được chuyển sang DataContractJsonSerializer nhưng serializer mặc định là tốt hơn) .

Vậy bạn có thể làm gì?Bạn có thể nói với serializer rằng nó nên theo dõi các tham chiếu vòng tròn đó bằng cách đánh dấu các lớp của bạn với DataContract(IsReference = true) và mỗi thuộc tính được truyền với thuộc tính DataMember (kiểm tra bài viết được liên kết để biết cách làm thế nào để đạt được nó với JSON.NET). Điều này sẽ cho phép serializer nhận chu kỳ chính xác và tuần tự hóa sẽ theo lý thuyết thành công. Về lý thuyết vì điều này cũng đòi hỏi không sử dụng tải chậm. Nếu không, bạn có thể serialize nhiều dữ liệu hơn bạn mong đợi (trong một số tình huống thảm khốc nó có thể dẫn đến serializing toàn bộ nội dung của cơ sở dữ liệu của bạn).

Khi bạn serialize biểu đồ thực với tải lười biếng cho phép bạn serailze một TopicCreator của nó nhưng serialization cũng sẽ thăm CreatedTopics tài sản => tất cả chủ đề liên quan là lười biếng nạp và xử lý bởi serialization và serialization tiếp tục đến thăm Creator của tất cả các chủ đề mới nạp ! Quá trình này tiếp tục cho đến khi không có đối tượng khác để tải lười. Bởi vì điều này bạn không bao giờ nên sử dụng tải lười biếng khi serializing thực thể.

Tùy chọn khác là loại trừ tham chiếu ngược lại khỏi tuần tự hóa. Bạn chỉ cần serialize Creator. Bạn không cần phải tuần tự hóa CreatedTopics để bạn có thể đánh dấu thuộc tính với thuộc tính IgnoreDataMember (JsonIgnore cho JSON.NET). Vấn đề là nếu bạn cũng có hành động API Web để trả lại User với tất cả các số CreateTopics của mình, điều này sẽ không hoạt động do thuộc tính.

Tùy chọn cuối cùng không sử dụng thực thể. Tùy chọn này thường được sử dụng trong các dịch vụ web nơi bạn tạo các đối tượng DTO đặc biệt đáp ứng các yêu cầu cho hoạt động cụ thể và bạn xử lý chuyển đổi giữa các thực thể và DTO bên trong hoạt động (có thể với trợ giúp của một số công cụ như AutoMapper).

Không có sự khác biệt giữa việc xử lý quan hệ một, một, nhiều hoặc nhiều. Nếu bạn có các thuộc tính điều hướng trên cả hai mặt, bạn phải luôn đối phó với vấn đề này.

+0

DataContractJsonSeriaizer Trình nối tiếp Json mặc định cho API Web API không? – Dean

+0

Tôi đang sử dụng tạm thời 'DataContract (IsReference = true)' và 'DataMember', có một bài viết chi tiết nói về điều này không? Tôi cũng quan tâm đến tùy chọn DTO, nhưng không thành công trong thời điểm này, sẽ dành nhiều thời gian hơn cho nó, và cảm ơn câu trả lời tốt. – Dean