本文介绍的Entity Framework跨数据库查询方法基于SQL Server的同义词。不了解同义词的朋友,可以参考相关资料,本文只是讲解实现方法。

准备工作

本文使用一个简单的订单例子来介绍,只不过我们的会员表,产品表,订单表分别放在了单独的数据库里,数据库结构如下图所示:

Entity Framework跨数据库查询-程序旅途

会员库EF_Member(只有一个User表)

Entity Framework跨数据库查询-程序旅途

产品库EF_Product(只有一个Product表)

Entity Framework跨数据库查询-程序旅途

订单库EF_Order(有Order和OrderItem两个表)

Entity Framework跨数据库查询-程序旅途

现在我们要做的就是定义一个订单的上下文,对订单进行查询。为了演示,我在订单里存了用户的Id,查询时需要到会员库里查询会员的姓名。这里在订单库里先定义两个同义词:

dbo.Member

USE [EF_Order]
GO

/****** Object:  Synonym [dbo].[Member]    Script Date: 03/25/2015 23:32:48 ******/
CREATE SYNONYM [dbo].[Member] FOR [EF_Member].[dbo].[User]
GO

dbo.Product

USE [EF_Order]
GO

/****** Object:  Synonym [dbo].[Product]    Script Date: 03/25/2015 23:33:41 ******/
CREATE SYNONYM [dbo].[Product] FOR [EF_Product].[dbo].[Product]
GO

如下图所示:

Entity Framework跨数据库查询-程序旅途

定义OrderContext上下文

下面定义OrderContext

    public partial class EFOrderContext : DbContext
    {
  
        public virtual DbSet<Order> Orders { get; set; }
        public virtual DbSet<OrderItem> OrderItems { get; set; }


        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            modelBuilder.Entity<Order>()
                .HasMany(e => e.OrderItem)
                .WithRequired(e => e.Order)
                .WillCascadeOnDelete(false);
        }
    }

下面为同义词定义实体,和为表定义实体一样 Member实体

    [Table("Member")]
    public class Member
    {
        [Key]
        public int UserId { get; set; }

        [Required]
        public string UserName { get; set; }

        [Required]
        public string Mobile { get; set; }
    }

Product实体

    [Table("Product")]
    public class Product
    {
        [Key]
        public int ProductId { get; set; }

        public string ProductName { get; set; }

        public decimal SalePrice  { get; set; }

    }

在Order实体中加入

public virtual Member Member { get; set; } 

在EFOrderContext中加入

public virtual DbSet<Member> Members { get; set; }

public virtual DbSet<Product> Products { get; set; }

modelBuilder.Entity<Order>()
     .HasRequired(t => t.Member)
     .WithMany()
     .HasForeignKey(t => t.MemberId);

 查询演示

到目前为止,我们就可以使用Entity Framework像操作一个数据库一样进行查询了。 比如,查询订单列表:

using (var ctx = new EFOrderContext())
{
    var orders = ctx.Orders.Select(t => new
    {
         t.OrderNo,
         t.Member.UserName,
         t.TotalMoney
    });
}

其实,这里将同义词看成普通的表进行操作就行了,配置属性和关系都和表一样,关于属性和关系的配置,请参考我的博客

本文的示例代码:https://github.com/mingceng/EFCrossDatabaseQuery