爆料:為什么Entity Framework不能進(jìn)行跨數(shù)據(jù)庫(kù)查詢
在上篇隨筆中提到“對(duì)于跨數(shù)據(jù)庫(kù)查詢,我們沒(méi)有找到通過(guò)LINQ to Entities實(shí)現(xiàn)的方法”。后來(lái)仔細(xì)想想,從理論來(lái)講,實(shí)現(xiàn)跨數(shù)據(jù)庫(kù)查詢應(yīng)該不難啊,與非跨數(shù)據(jù)庫(kù)查詢相比,只是多了個(gè)數(shù)據(jù)庫(kù)名,比如下面的非跨數(shù)據(jù)庫(kù)查詢語(yǔ)句:
- SELECT [Text] FROM dbo.blog_PostBody WHERE ID=3560
跨數(shù)據(jù)庫(kù)查詢語(yǔ)句:
- SELECT [Text] FROM CNBlogsText.dbo.blog_PostBody WHERE ID=3560
在Entity Framework中,我們可以通過(guò)ToTable("表名")指定表名進(jìn)行映射,Entity Framework會(huì)根據(jù)指定的表名構(gòu)建SQL語(yǔ)句,如果在這里加上數(shù)據(jù)庫(kù)名和Schema名(也就是ToTable("數(shù)據(jù)庫(kù).dbo.表名")),是不是可以實(shí)現(xiàn)跨數(shù)據(jù)庫(kù)查詢呢?
于是,我們根據(jù)這個(gè)思路進(jìn)行了試驗(yàn),結(jié)果發(fā)現(xiàn)了Entity Framework不能進(jìn)行跨數(shù)據(jù)庫(kù)查詢的秘密:Entity Framework會(huì)對(duì)ToTable()中指定的表名進(jìn)行處理,加上中括號(hào),如果沒(méi)有指定Schema名,會(huì)在表名前加上[dbo],比如:ToTable("表名"),SQL語(yǔ)句中的表名是[dbo].[表名]。而在加“中括號(hào)”時(shí)的不正確有處理,成為了罪魁禍?zhǔn)住?/p>
我們?cè)噲D組裝一些特殊字符串騙過(guò)Entity Framework,都沒(méi)成功。目前我們?cè)谟肦eflector在Entity Framework的代碼中尋找兇手,只有找到了兇手,知道了作案手段,才能知道是否有可能解決這個(gè)問(wèn)題。
下面用代碼爆一下料:
BlogDbContext的代碼:
- public class BlogDbContext : DbContext
- {
- public DbSet<PostText> PostTexts { get; set; }
- protected override void OnModelCreating(DbModelBuilder modelBuilder)
- {
- modelBuilder.Entity<PostText>().ToTable("blog_PostBody");
- }
- }
LINQ to Entities查詢代碼:
- using (BlogDbContext context = new BlogDbContext())
- {
- (from t in context.PostTexts
- where t.ID == 3560
- select t.Text).FirstOrDefault();
- }
1. 這是非跨數(shù)據(jù)庫(kù)查詢的情況,生成的SQL語(yǔ)句如下:
- SELECT TOP (1)
- [Extent1].[Text] AS [Text]
- FROM [dbo].[blog_PostBody] AS [Extent1]
- WHERE 3560 = [Extent1].[ID]
指定的表名是blog_PostBody,SQL語(yǔ)句中變成了[dbo].[blog_PostBody]。
2. 跨數(shù)據(jù)庫(kù)查詢:
BlogDbContext的代碼改為:
- modelBuilder.Entity<PostText>().ToTable("CNBlogsText.dbo.blog_PostBody");
生成的SQL語(yǔ)句:
- SELECT TOP (1)
- [Extent1].[Text] AS [Text]
- FROM [CNBlogsText.dbo].[blog_PostBody] AS [Extent1]
- WHERE 3560 = [Extent1].[ID]
CNBlogsText.dbo被整個(gè)加在了中括號(hào)中,正確的應(yīng)該是[CNBlogsText].[dbo].[blog_PostBody]。
試圖欺騙一下Entity Framework,將表名改為:
- modelBuilder.Entity<PostText>().ToTable("CNBlogsText].[dbo.blog_PostBody");
生成的SQL語(yǔ)句:
- SELECT TOP (1)
- [Extent1].[Text] AS [Text]
- FROM [CNBlogsText]].[dbo].[blog_PostBody] AS [Extent1]
- WHERE 3560 = [Extent1].[ID]
多出了半個(gè)中括號(hào),欺騙失敗...
要想真相大白,只有找出Entity Framework中這部分處理的代碼,昨天用Reflector苦苦尋覓了一個(gè)晚上未果,今天繼續(xù)尋覓...
原文鏈接:http://www.cnblogs.com/dudu/archive/2011/03/29/entity_framework_cross_database_query.html
【編輯推薦】