2014年4月7日 星期一

ASP.NET MVC 4 Controller 使用委派 ( delegate ) 做更進階的篩選

委派是事件的基礎。

將委派與具名方法或匿名方法建立關聯,即可具現化 (Instantiated) 委派。 如需詳細資訊,請參閱具名方法匿名方法
委派必須以具有相容傳回型別和輸入參數的方法或 Lambda 運算式具現化。 如需方法簽章中可允許之變異數等級的詳細資訊,請參閱委派中的變異數 (C# 和 Visual Basic)。 若要搭配匿名方法使用,就要同時宣告委派以及其相關聯的程式碼。

以上引用:delegate (C# 參考)

方便處在於可以在類別上宣告後,即可在各個方法函數內使用,可以依照方法不同,而產生結果也不同,但是只用同一委派 ( delegate ) 實現。

這裡使用北風資料庫來實作委派,沒有資料庫的話可以參考:Visual Studio 2012 安裝 Northwind 資料庫並建立 Entity Framework Database First ( .edmx )

在 Controller 中撰寫,傳入訂單編號來搜尋訂單下的訂單細項之產品的名稱,單位價格區間。

先看看資料庫關聯表:

先宣告委派,並且決定傳入傳出參數,關鍵字、最小價格、最大價格:
delegate bool SearchProduct(Order_Details order_detail, string keyword, decimal mixprice, decimal minprice);

類別內宣告委派:
SearchProduct sp;

最後在 Controller 實作並且使用委派:
[HttpGet]
public IEnumerable<Order_Details> SearchProduct(int orderid, string keyword, decimal minprice, decimal maxprice)
{
    sp = (o, k, min, max) =>
    {

        return o.Products.ProductName.Contains(k) ||
               o.Products.UnitPrice >= min &&
               o.Products.UnitPrice <= max;
    };

    var Order_Details = db.Order_Details
        .Include(x => x.Products)
        .Where(x => x.Orders.OrderID == orderid)
        .ToList()
        .Where(x => sp(x, keyword, minprice, maxprice));

    foreach (Order_Details _order_detail in Order_Details)
    {
        _order_detail.Products.Order_Details = null;
    }

    return Order_Details; 
}

執行後呼叫 API - http://localhost:8090/api/Product/SearchProduct?orderid=10285&keyword=Ch&maxprice=18&minprice=17,得到結果:
[
    {
        "OrderID": 10285,
        "ProductID": 1,
        "UnitPrice": 14.4,
        "Quantity": 45,
        "Discount": 0.2,
        "Orders": null,
        "Products": {
            "ProductID": 1,
            "ProductName": "Chai",
            "SupplierID": 1,
            "CategoryID": 1,
            "QuantityPerUnit": "10 boxes x 20 bags",
            "UnitPrice": 18,
            "UnitsInStock": 39,
            "UnitsOnOrder": 0,
            "ReorderLevel": 10,
            "Discontinued": false,
            "Categories": null,
            "Order_Details": null,
            "Suppliers": null
        }
    }
]

為何不在 LINQ 內使用條件判斷? 其實我已經實作過了,會出現「運算式樹狀架構可能不含指派運算子」錯誤,且必須要實例化出來才可以做,以下錯誤程式碼:
[HttpGet]
public IEnumerable<Order_Details> SearchProduct(int orderid, string keyword, decimal minprice, decimal maxprice)
{

    Products _product;

    var Order_Details = db.Order_Details
        .Include(x => x.Products)
        .Where(x => x.Orders.OrderID == orderid &&
            (
                (_product = x.Products) != null &&
                _product.ProductName.Contains(keyword) ||
                _product.UnitPrice >= minprice ||
                _product.UnitPrice <= maxprice
            )

        ).ToList();

    return Order_Details; 
}


沒有留言 :

張貼留言

Related Posts Plugin for WordPress, Blogger...