本文介绍的Entity Framework跨数据库查询方法基于SQL Server的同义词。不了解同义词的朋友,可以参考相关资料,本文只是讲解实现方法。
准备工作
本文使用一个简单的订单例子来介绍,只不过我们的会员表,产品表,订单表分别放在了单独的数据库里,数据库结构如下图所示:
会员库EF_Member(只有一个User表)
产品库EF_Product(只有一个Product表)
订单库EF_Order(有Order和OrderItem两个表)
现在我们要做的就是定义一个订单的上下文,对订单进行查询。为了演示,我在订单里存了用户的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
如下图所示:
定义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
});
}
其实,这里将同义词看成普通的表进行操作就行了,配置属性和关系都和表一样,关于属性和关系的配置,请参考我的博客
咨询下,这样配置,在迁移数据库的时候系统不会自动再生成一个Member的表吗