代码优先实体框架可以在同一个框中与SQL Server DB交叉数据库查询吗?

mat*_*mc3 13 sql-server entity-framework ef-code-first

我知道有很多关于Entity Framework在发布到stackoverflow的同一服务器上进行跨数据库查询的问题.大多数情况下,答案似乎是"不",并且引用了2008年的这种联系.然而,实体框架一直在变化,并且CTP5出来了,我想知道答案是否仍然相同 - 你不能这样做,或者如果你手动编辑edmx文件就可以做到,或者你有使用视图.仅此功能就是我仍然依赖于Linq-to-SQL的原因,因为我们在同一台服务器上有多个SQL Server 2008数据库,需要对它们进行查询.使用数百个select *视图对我们的数据库进行污染不是一种选择,使用代码优先开发我没有要编辑的edmx文件.我正在玩pubs数据库,看看我是否可以到达某个地方,但我被卡住了.有什么建议?

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.ComponentModel.DataAnnotations;
using System.Data.Entity;
using System.Data.Entity.ModelConfiguration;

namespace DbSchema {
    public class Employee {
        [Key]
        public string ID { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public short JobID { get; set; }
        public Job Job { get; set; }
    }

    public class Job {
        [Key]
        public short ID { get; set; }
        public string Description { get; set; }
    }

    public class PubsRepository : DbContext {
        public DbSet<Employee> Employee { get; set; }
        public DbSet<Job> Job { get; set; }

        protected override void OnModelCreating(ModelBuilder modelBuilder) {
            // employee
            var eeMap = modelBuilder.Entity<Employee>();
            eeMap.ToTable("employee", "dbo"); // <-- how do I reference another database?
            eeMap.Property(e => e.ID).HasColumnName("emp_id");
            eeMap.Property(e => e.FirstName).HasColumnName("fname");
            eeMap.Property(e => e.LastName).HasColumnName("lname");
            eeMap.Property(e => e.JobID).HasColumnName("job_id");

            // job
            var jobMap = modelBuilder.Entity<Job>();
            jobMap.Property(j => j.ID).HasColumnName("job_id");
            jobMap.Property(j => j.Description).HasColumnName("job_desc");
        }

        public List<Employee> GetManagers() {
            var qry = this.Employee.Where(x => x.Job.Description.Contains("manager"));
            Debug.WriteLine(qry.ToString());
            return qry.ToList(); // <-- error here when referencing another database!
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

Shi*_*iji 12

我认为答案仍然没有,但有办法绕过它.

之所以不是,EF使用DBContext,上下文有连接字符串,连接字符串转到数据库.

以下是两种方法:

  • 对每个数据库使用2个不同的上下文,这意味着将数据带到客户端并在客户端上合并它.
  • 在数据库上使用链接表,通过视图提取数据,以便EF将其视为来自单个数据库.

在您的代码中,您似乎使用2个dbcontexts


小智 5

有两种方法可以做到这一点.

当然,一个是在其中一个数据库中创建一个视图,该数据库执行跨数据库查询,然后像访问任何其他视图一样从模型中访问视图.

另一种是通过创建一个在模型本身内创建相同的跨数据库查询视图DefiningQuery.这与使用SQLClient的方式最相似.在SQLClient中,您将在T-SQL中创建视图作为SQLCommand的文本,然后执行命令以创建数据读取器或数据表.在这里,您使用相同的T-SQL创建DefiningQuery,然后将其与您手动创建的实体链接起来.这有点工作,但它完全符合您的要求.

以下是使用链接DefiningQuerys:http://msdn.microsoft.com/en-us/library/cc982038.aspx.

如果你碰巧有来自O'Reilly的Lerman 所着的" 编程实体框架 " 一书,那么第16章就是一个很好的例子.

所以你必须跳过一些箍来做你以前直接用SQLClient做的事情,但是你得到了建模的实体.