解決Entity Framework查詢匿名物件後的跨域訪問的一種方式
在Entity Framework中,可以使用lambda表示式進行對資料的查詢,而且可以將查詢結果直接對映為物件或者物件列表,這極大的提高的開發速度,並且使資料層的資料更加方便處理和傳遞。但是很多時候,我們不需要把整個表的欄位都查出來,如果我們直接把整個資料實體查詢出來,就極大的影響了效能,所以我們需要通過查詢匿名物件或者已經定義的方式,對資料庫進行查詢;
1.例項使用的資料實體類:
public class Category { public int Id { get; set; } public string Name { get; set; } public string Description { get; set; } }
2.查詢
假設我們需要現實一個分類目錄,我們只需要Id和Name兩個欄位,我們可以建立一個新的CategoryView
public class CategoryView
{
public int Id { get; set; }
public string Name { get; set; }
}
查詢的時候,可以這樣做,讓它直接生成CategoryView的列表:
var data1 = from c in context.Categoriees select new CategoryView() { Id = c.Id, Name = c.Name };
這樣,可以在將方法返回值設定為IQueryable<CategoryView>型別,在呼叫方法處可以直接遍歷;
然而,當沒有CategoryView的時候,我們就只能使用匿名物件進行查詢:
var data = from c in context.Categoriees select new { cId = c.Id, cName = c.Name };
這樣的查詢之後,同樣可以直接通過cId和cName取值,但是僅限當前方法內部,如果跨域訪問的話,就沒法直接讀出cId和cName的值了:
CategoryService類的實現如下所示:
namespace ConsoleApplication1
{
public class CategoryService
{
private ShopContext context=new ShopContext();
public IQueryable<object> GetAllCategories()
{
var data = from c in context.Categoriees
select new
{
cId = c.Id,
cName = c.Name
};
return data;
}
}
}
呼叫方法:
CategoryService service=new CategoryService();
IQueryable<object> data = service.GetAllCategories();
這時,我們是沒法直接讀取object型別的屬性值的,在不考慮效能的前提下,我們可以使用反射,得到屬性值:
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
CategoryService service=new CategoryService();
IQueryable<object> data = service.GetAllCategories();
foreach (var item in data)
{
Type type = item.GetType();
PropertyInfo idProperty = type.GetProperty("cId");
string id = idProperty.GetValue(item, null).ToString();
PropertyInfo nameProperty = type.GetProperty("cName");
string name = nameProperty.GetValue(item, null).ToString();
Console.WriteLine("Id:"+id+" Name:"+name);
}
Console.ReadKey();
}
}
}
當然,這樣的操作,如果您覺得效能的問題不比需要建立CategoryView模型類造成的麻煩多的話,還是一種比較簡單快捷的實現方式,但是我的建議還是建立像CategoryView這樣的檢視模型類,可以發這個類物件傳遞給檢視直接顯示,何樂不為!!!
3.目前為止我所知的最好的跨域訪問方式
在c#4.0中,加入了dynamic特性,這使得我們可以使用它支援對動態型別的解釋,雖然c#語言絕對是靜態型別的,但是dynamic通過在編譯的時候,不推斷出具體型別,而是展開為表示式數的形式,在最後執行期間使用代理去執行呼叫的方法,是對匿名型別的呼叫比使用反射機制更加高效便捷了,所以,對於上述例項,可以使用如下方式進行呼叫:
foreach (dynamic item in data)
{
Console.WriteLine(item.cId);
}
而我們失去的,只是visual studio的智慧提示而已,所以目前看來,這是最適當的一種方法,當然,如果是和UI層連結的服務層,我仍然推薦使用查詢ViewModel的方式