我在做一個以Northwind為數據庫,使用EDM、ASP.NET MVC1.0框架的示例項目。項目剛剛開始,目前在做一些技術測試。當對實體層進行操作時,問題來了。
問題:對對象集進行查詢的時候,我們往往不需要查詢所有的字段,但返回的時候卻要返回這個對象或對象結合。這是我們該如何做?
例如:Categories這個表(在EDM中為Category類)中包含了Picture這個字段,Picture是存放圖片的,數據相對比較大,那我們在讀取這個表的時候每次都全部取出數據勢必不是一個高效的做法。
解決過程:
首先,我們在需要查詢特定字段的時候使用 Entity SQL來進行操作。
例如我們只要查詢Category的CategoryID,CategoryName字段
那麼我們可以這樣做:
string esqlCommand= "SELECT c.CategoryID,c.CategoryName FROM NorthwindEntities.Category AS c";
using (NorthwindEntities northwind = new NorthwindEntities())
{
List<Object> readers = northwind.CreateQuery<Object>(esqlCommand).ToList();
//List<Obect> readers = (from c in northwind.Category select new { CategoryID = c.CategoryID,CategoryName = c.CategoryName).ToList();第二種方法
//這裡無法使用northwind.CreateQuery<Category>,因為執行完上面的esqlCommand後返回的是匿名類型,它無法如此轉換成Entity類型
//這就是問題關鍵。
}
第一次想到的方法是
class MyCategory:Category{}//MyCategory類繼承Category類也就繼承了它的屬性,這樣我就可以使結果返回MyCategory
string esqlCommand= "SELECT c.CategoryID,c.CategoryName FROM NorthwindEntities.Category AS c";
using (NorthwindEntities northwind = new NorthwindEntities())
{
List<MyCategory> readers = (from c in northwind.Category select new MyCategory { CategoryID = c.CategoryID,CategoryName = c.CategoryName).ToList();
//這裡無法使用northwind.CreateQuery<Category>,因為執行完上面的esqlCommand後返回的是匿名類型,它無法如此轉換成Entity類型
//這就是問題關鍵。
}
OK,但是以後每個類你都要增加各MyClass,而且這個類也使實體層顯得不“干淨”。這時候想到了使用反射來對把結果轉換成我們要的實體,上網看了dudu的CN.Text開發筆記—利用反射將數據讀入實體類。以下是在dudu基礎上寫的方法。
public class Shared
{
private static void ReaderToEntity(IDataRecord reader, Object entity)
{
for (int i = 0; i < reader.FieldCount; i++)
{
System.Reflection.PropertyInfo propertyInfo = entity.GetType().GetProperty(reader.GetName(i));
if (propertyInfo != null)
{
if (reader.GetValue(i) != DBNull.Value)
{
propertyInfo.SetValue(entity, reader.GetValue(i), null);
}
}
}
}
public static T ExecToEntity<T>(string esqlCommand)
{
DbDataRecord reader;
using (NorthwindEntities northwind = new NorthwindEntities())
{
reader = northwind.CreateQuery<DbDataRecord>(esqlCommand).FirstOrDefault();
}
if (reader == null)
{
return default(T);
}
else
{
T entity = (T)Activator.CreateInstance(typeof(T));
ReaderToEntity(reader, entity);
return entity;
}
}
public static List<T> ExecToEntities<T>(string esqlCommand)
&n