2011年10月26日 星期三

使用Entity Framework 將物件轉為JSON時遇到循環參考錯誤 2


接續「使用Entity Framework 將物件轉為JSON時遇到循環參考錯誤 1

public ActionResult Product(int? id)
{
    if (!id.HasValue)
    {
        Dictionary<string, string> jo = new Dictionary<string, string>();
        jo.Add("Msg", "請輸入產品ID編號.");
        return Content(JsonConvert.SerializeObject(jo), "application/json");
    }
    else
    {
        ProductService service = new ProductService();
        var product = service.Single(id.Value);
        var result = new
        {
            ProductID = product.ProductID,
            ProductName = product.ProductName,
            SupplierID = product.SupplierID,
            CategoryID = product.CategoryID,
            CategoryName = product.Category.CategoryName,
            QuantityPerUnit = product.QuantityPerUnit,
            UnitPrice = product.UnitPrice,
            UnitsInStock = product.UnitsInStock,
            UnitsOnOrder = product.UnitsOnOrder,
            ReorderLevel = product.ReorderLevel
        };
        return Content(JsonConvert.SerializeObject(result), "application/json");
    }
}

上面的程式是把Product物件取出後,再去指定要序列化為JSON時所要用的欄位,

但如果每次要對物件做序列化時都要這樣手動去指定也算是一件蠻累人的事情,

尤其是欄位多的時候以及一個物件會在多個地方去做序列化為JSON的操作時,一再重複這樣的事情就會覺得煩。


其實我們可以去修改Edmx的屬性設定,讓原本的關聯載入設定為不啟動,這樣一來就只會載入物件本身的資料。

修改Entity Framework的Edmx屬性「消極式載入已啟用」

image

原本的預設值式設定為「True」,所以這裡就改為「False」

image

 

為什麼要改這個「消極式載入」的設定呢?

就如一開始說到,這個設定預設為True,所以當取出一個物件時,如果有關連的資料,就會載入關連的資料,

而我們將這設定改為False之後,取出的物件就不會包含關連的物件資料,

而更改設定後,如果需要載入關連的物件資料要怎麼做呢?我們還是可以使用 Include 方法或是 LoadProperty 方法來明確載入,

看看MSDN是怎麼說的…

HOW TO:使用消極式載入來載入相關物件 (Entity Framework)

 

我們修改好Edmx的「消極式載入已啟用」為False之後,先來看看以下的程式執行之後的結果,

程式之中,我們就是直接把取出的物件給放到JsonConvert.SerializeObject()方法,

public ActionResult Product(int? id)
{
    if (!id.HasValue)
    {
        Dictionary<string, string> jo = new Dictionary<string, string>();
        jo.Add("Msg", "請輸入產品ID編號.");
        return Content(JsonConvert.SerializeObject(jo), "application/json");
    }
    else
    {
        ProductService service = new ProductService();
        var product = service.Single(id.Value);
        return Content(JsonConvert.SerializeObject(product), "application/json");
    }
}

執行結果:

image

上面的執行結果可以看到後端輸出的JSON資料大小只有427B而關連的資料則不會載入。

 

以程式的方式去修改載入設定

如果我們使用Entity Framework工具來建立實體模型以及產生實體類別,

那麼Edmx的消極式載入已啟用會預設為true之外,而ObjectContext的LazyLoadingEnabled會設定為true,

如果不想去修改Edmx的屬性設定的話,也可以在程式中將LazyLoadingEnable屬性設定為false

這樣一來取出的物件也不會載入關連的物件資料,而序列化為JSON就不會有循環參考的錯誤。

this._context.ContextOptions.LazyLoadingEnabled = false;
image

參考連結:

MSDN - ObjectContextOptions.LazyLoadingEnabled 屬性

 

以上

沒有留言:

張貼留言

提醒

千萬不要使用 Google Talk (Hangouts) 或 Facebook 及時通訊與我聯繫、提問,因為會掉訊息甚至我是過了好幾天之後才發現到你曾經傳給我訊息過,請多多使用「詢問與建議」(在左邊,就在左邊),另外比較深入的問題討論,或是有牽涉到你實作程式碼的內容,不適合在留言板裡留言討論,請務必使用「詢問與建議」功能(可以夾帶檔案),謝謝。