• 爆料:为什么Entity Framework不能进行跨数据库查询


    上篇随笔中提到“对于跨数据库查询,我们没有找到通过LINQ to Entities实现的方法”。后来仔细想想,从理论来讲,实现跨数据库查询应该不难啊,与非跨数据库查询相比,只是多了个数据库名,比如下面的非跨数据库查询语句:

    SELECT [Text] FROM dbo.blog_PostBody WHERE ID=3560

    跨数据库查询语句:

    SELECT [Text] FROM CNBlogsText.dbo.blog_PostBody WHERE ID=3560

    在Entity Framework中,我们可以通过ToTable("表名")指定表名进行映射,Entity Framework会根据指定的表名构建SQL语句,如果在这里加上数据库名和Schema名(也就是ToTable("数据库.dbo.表名")),是不是可以实现跨数据库查询呢?

    于是,我们根据这个思路进行了试验,结果发现了Entity Framework不能进行跨数据库查询的秘密:Entity Framework会对ToTable()中指定的表名进行处理,加上中括号,如果没有指定Schema名,会在表名前加上[dbo],比如:ToTable("表名"),SQL语句中的表名是[dbo].[表名]。而在加“中括号”时的不正确有处理,成为了罪魁祸首。

    我们试图组装一些特殊字符串骗过Entity Framework,都没成功。目前我们在用Reflector在Entity Framework的代码中寻找凶手,只有找到了凶手,知道了作案手段,才能知道是否有可能解决这个问题。

    下面用代码爆一下料:

    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. 这是非跨数据库查询的情况,生成的SQL语句如下:

    SELECT TOP (1)
    [Extent1].[Text] AS [Text]
    FROM [dbo].[blog_PostBody] AS [Extent1]
    WHERE 3560 = [Extent1].[ID]
    指定的表名是blog_PostBody,SQL语句中变成了[dbo].[blog_PostBody]。

    2. 跨数据库查询:

    BlogDbContext的代码改为:

    modelBuilder.Entity<PostText>().ToTable("CNBlogsText.dbo.blog_PostBody");

    生成的SQL语句:

    SELECT TOP (1)
    [Extent1].[Text] AS [Text]
    FROM [CNBlogsText.dbo].[blog_PostBody] AS [Extent1]
    WHERE 3560 = [Extent1].[ID]
    CNBlogsText.dbo被整个加在了中括号中,正确的应该是[CNBlogsText].[dbo].[blog_PostBody]。

    试图欺骗一下Entity Framework,将表名改为:

    modelBuilder.Entity<PostText>().ToTable("CNBlogsText].[dbo.blog_PostBody");

    生成的SQL语句:

    SELECT TOP (1)
    [Extent1].[Text] AS [Text]
    FROM [CNBlogsText]].[dbo].[blog_PostBody] AS [Extent1]
    WHERE 3560 = [Extent1].[ID]

    多出了半个中括号,欺骗失败...

    要想真相大白,只有找出Entity Framework中这部分处理的代码,昨天用Reflector苦苦寻觅了一个晚上未果,今天继续寻觅...

    该问题已解决,见:真相大白:为什么Entity Framework不能进行跨数据库查询(附解决方法)

  • 相关阅读:
    【STM32H7教程】第22章 STM32H7的SysTick实现多组软件定时器
    【STM32H7教程】第21章 STM32H7的NVIC中断分组和配置(重要)
    【STM32H7教程】第20章 STM32H7的GPIO应用之无源蜂鸣器
    【STM32H7教程】第19章 STM32H7的GPIO应用之按键FIFO
    【STM32H7教程】第18章 STM32H7的GPIO应用之跑马灯
    【STM32H7教程】第17章 STM32H7之GPIO的HAL库API
    【STM32H7教程】第16章 STM32H7必备的HAL库API(重要)
    【STM32H7教程】第15章 STM32H7的GPIO基础知识(重要)
    git源码安装
    mysql创建用户与授权
  • 原文地址:https://www.cnblogs.com/dudu/p/entity_framework_cross_database_query.html
Copyright © 2020-2023  润新知