Entity Framework 4.1 and Poco 使用存儲過程聯表查詢
一:數據庫支持
為了演示本例,我們創建了另外一個簡單的示例數據庫MiniNW,該數據庫來自于ADO.NET Entity Framework Extensions,但在本例中,我們不會使用這個針對EF的擴展框架,因為它對POCO的支持不好,同時它也不支持DbContext,簡單的說來就是它目前不支持EF4.1。
MiniNW可以在本示例代碼的如下位置獲得:
數據庫對應關系如下(由于數據庫相對簡單,所以直接列出數據,從數據可以直觀看出兩表的關系):
二:生成POCO及DbContext
我們使用Entity Framework Power Tools CTP生成POCO及相關映射,如果你對此不熟悉,可參考本篇《使用Entity Framework和WCF Ria Services開發SilverLight之3:Map》。
三:主表從表數據一起關聯查詢
數據庫中存在存儲過程GetCategory:
ALTER proc [dbo].[GetCategory]
@cid int
as
begin
select *
from Categories
where @cid = cid
end
執行此存儲過程的代碼如下:
public IEnumerable<Category> GetCategoryWithProductsWithID(int id)
{
var parameter = new SqlParameter
{
DbType = DbType.Int32,
ParameterName = "cid",
Value = id
};
//聯表并延遲加載
var result = (from p in this.Categories.SqlQuery("EXECUTE GetCategory @cid", parameter) select p).ToList();
return result;
}
得到的數據如下:
其中,Category所對應Products是延遲加載進來的,如果我們只使用Category,數據引擎就不會查詢Products表的數據,但是,只要我們一到Category中查看Products,就會獲取如上圖這樣的Products數據。請根據源碼中的兩個數據實體理解。
執行存儲部分的代碼EF為我們生成如下:
exec sp_executesql N'EXECUTE GetCategory @cid',N'@cid int',@cid=1
延遲加載部分的代碼EF為我們生成如下:
exec sp_executesql N'SELECT [Extent1].[pid] AS [pid], [Extent1].[name] AS [name], [Extent1].[discontinued_date] AS [discontinued_date], [Extent1].[cid] AS [cid] FROM [dbo].[Products] AS [Extent1] WHERE [Extent1].[cid] = @EntityKeyValue1',N'@EntityKeyValue1 int',@EntityKeyValue1=1
三:僅獲取主表數據
如果不需要關聯表的數據,我們可以像下面這樣編碼。以下這段代碼使用的是和上文一樣的存儲過程:
public IEnumerable<Category> GetCategoryWithID(int id)
{
var parameter = new SqlParameter
{
DbType = DbType.Int32,
ParameterName = "cid",
Value = id
};
//非聯表
var result = (from p in this.Categories.SqlQuery("EXECUTE GetCategory @cid", parameter)
select new
{
cid = p.cid,
name = p.name
}).ToList()
.Select(r => new Category()
{
cid = r.cid,
name = r.name
});
return result;
}
如果你對這段代碼表示不很理解,請參看此文《使用Entity Framework和WCF Ria Services開發SilverLight之6:查找指定字段》。
獲取數據如下:
四:由從表關聯主表數據
從表關聯主表的存儲過程如下:
ALTER proc [dbo].[GetProductAndCategory]
@pid int
as
begin
select p.pid, p.[name] , p.discontinued_date, c.cid, c.[name]
from Products as p join Categories as c on p.cid = c.cid
where p.pid = @pid
end
注意,原始例子所帶的存儲過程不是這樣的,多了這樣的語句:
DbContext默認支持實體類型的字段和數據庫視圖是一個字段名,所以我們去掉了重命名部分。
實現此功能的代碼如下:
public IEnumerable<Product> GetProductAndCategoryWithID(int id)
{
var parameter = new SqlParameter
{
DbType = DbType.Int32,
ParameterName = "pid",
Value = id
};
//延遲加載
var result = (from p in this.Products.SqlQuery("EXECUTE dbo.GetProductAndCategory @pid", parameter) select p).ToList();
return result;
}
要注意,主表的數據也是延遲加載的,只有使用到的時候才會被查詢。
EF為我們生成的代碼如下:
exec sp_executesql N'EXECUTE dbo.GetProductAndCategory @pid',N'@pid int',@pid=1
獲取的數據如下:







浙公網安備 33010602011771號