下班前,给大家分享一下今天研究Entity Framework的LINQ查询的一点小收获。
先看LINQ查询代码(是一个JOIN查询):
using
(BlogDbContext context
=
new
BlogDbContext())
{
var result = (from e in context.BlogEntries
join t in context.PostTexts
on e.ID equals t.ID
where e.ID == 3560
select new
{
Title = e.Title,
Body = t.Text
}
);
Console.WriteLine(result.ToString());
}
{
var result = (from e in context.BlogEntries
join t in context.PostTexts
on e.ID equals t.ID
where e.ID == 3560
select new
{
Title = e.Title,
Body = t.Text
}
);
Console.WriteLine(result.ToString());
}
这看似一个查询,实际没有进行实际数据的查询,但Entity Framework确实在数据库中进行了查询。有些绕口,还是看代码,看真相。
result.ToString()的输出结果是:
SELECT
[ Extent1 ] . [ ID ] AS [ ID ] ,
[ Extent1 ] . [ Title ] AS [ Title ] ,
[ Extent2 ] . [ Text ] AS [ Text ]
FROM [ dbo ] . [ blog_Content ] AS [ Extent1 ]
INNER JOIN [ dbo ] . [ CNBlogsText__blog_PostBody ] AS [ Extent2 ] ON [ Extent1 ] . [ ID ] = [ Extent2 ] . [ ID ]
WHERE 3560 = [ Extent1 ] . [ ID ]
[ Extent1 ] . [ ID ] AS [ ID ] ,
[ Extent1 ] . [ Title ] AS [ Title ] ,
[ Extent2 ] . [ Text ] AS [ Text ]
FROM [ dbo ] . [ blog_Content ] AS [ Extent1 ]
INNER JOIN [ dbo ] . [ CNBlogsText__blog_PostBody ] AS [ Extent2 ] ON [ Extent1 ] . [ ID ] = [ Extent2 ] . [ ID ]
WHERE 3560 = [ Extent1 ] . [ ID ]
Entity Framework生成了上面的SQL语句(很标准的INNER JOIN查询),但没有把它交给数据库。
同时,我们用SQL Server Profiler监视Entity Framework的一举一动,看有没有黑幕...
嘿嘿,逮个正着,Entity Framework偷偷与数据库进行两次交易:
第一次交易:
SELECT
Count
(
*
)
FROM
sys.databases
WHERE
[
name
]
=
N
'
CNBlogsData
'
第二次交易:
SELECT
TOP
(
1
)
[ Extent1 ] . [ Id ] AS [ Id ] ,
[ Extent1 ] . [ ModelHash ] AS [ ModelHash ]
FROM [ dbo ] . [ EdmMetadata ] AS [ Extent1 ]
ORDER BY [ Extent1 ] . [ Id ] DESC
[ Extent1 ] . [ Id ] AS [ Id ] ,
[ Extent1 ] . [ ModelHash ] AS [ ModelHash ]
FROM [ dbo ] . [ EdmMetadata ] AS [ Extent1 ]
ORDER BY [ Extent1 ] . [ Id ] DESC
第二个交易让人莫明其妙,数据库中根本不存在[EdmMetadata]这个表,如果比喻一下,就是说Entity Framework想敲诈数据库的钱,可数据库没钱,这不是浪费感情嘛。
拒绝黑幕,拒绝浪费感情,目前找到了禁止第二个交易的方法:
public
class
BlogDbContext : DbContext
{
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Conventions.Remove < IncludeMetadataConvention > ();
}
}
{
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Conventions.Remove < IncludeMetadataConvention > ();
}
}
但第一个交易还不能确定是不是黑幕,也不知道如何禁止。