使用实体框架从两个数据库连接表

时间:2014-10-19 00:53:56

标签: asp.net-mvc linq entity-framework entity-framework-5

我正在开发一个ASP.NET MVC 4 Web应用程序。我使用Entity Framework作为数据访问层,使用数据库第一种方法(.edmx文件)。

目前我在两个不同数据库中定义的连接表中存在问题(即我有两个.edmx个文件)。

例如,如果我想连接表,我正在执行以下查询: -

public ActionResult AutoComplete(string term)
{
   var tech = repository.AllFindTechnolog(term).Take(100);//Call to the first database
   var resources = repository.GetResources(tech.Select(a => a.IT360ID.Value).ToArray(), false);//call to the second database

   var query = from techItems in tech
         join resourcesItems in resources
         on techItems.IT360ID.Value equals resourcesItems.RESOURCEID // join based on db2ID
         orderby techItems.PartialTag
         select new //code goes here

   return Json(query, JsonRequestBehavior.AllowGet);
}

我将对数据库进行两次单独调用,并在应用程序服务器内部进行连接,这不是最佳的面向性能的解决方案。理想情况下,连接将完全发生在数据库引擎内。

我知道存储过程将允许我纯粹在服务器上连接来自不同数据库的表,但我不想使用SP,因为它会使我的代码不易维护且不易测试。

所以我正在寻找一个解决方案,我可以使用实体框架进行连接并产生单个数据库连接?

4 个答案:

答案 0 :(得分:4)

如果您想通过单个数据库调用来执行此操作,则必须在数据库中创建一个View,该View将连接来自不同数据库的2个表。创建视图后,您可以将其作为单个对象添加到EF,您可以进一步操作和查询。该视图基本上是一个表格,它易于维护,易于绑定到强类型模型

另一种方式,就像您发布的类似,您可以查询单独的.edmx文件,然后加入它们。 是的,有两个电话号码,但它不应该那么昂贵,可能不会注意到差异。

using(var db = new MyEntities())
using (var db2 = new MyEntities2())
{
   var one = db.Table1.AsEnumerable();
   var two = db2.Table2.AsEnumerable(); 

   var result = from o in one
                join t in two on o.Id equals t.Id
                // blah blah

}

答案 1 :(得分:2)

@ CSharper的答案很接近。正如@Oliver在评论中提到的那样,IEnumerable将表加载到应用程序内存中,如果你有一个大型数据库会导致崩溃。

解决方案是使用IQueryable,可以使用LINQ调用 - 这会产生更快的SQL。

// This is a generic method, modify to your needs
public ActionResult Details(int? id)
   var one = db.Table1.AsQueryable();
   var two = db2.Table2.AsQueryable(); 

   // since you're using MVC EF, I assume you want to put this in a viewmodel 
   // (in this case ObjectCombined)
   // assume "id" is passed as parameter 
   Object1 result1 = (from o in one where one.id == id select o).Single();
   Object2 result2 = (from t in two where t.id == o.id select t).Single();
   ObjectCombined result = new ObjectCombined(result1, result2);
   return View(result);
}

答案 2 :(得分:0)

我建议您考虑在数据库中使用synonym。例如,您可以创建技术表所在的数据库中资源表的同义词。这将确保您不需要维护2个EDMX文件。相反,你可以拥有一个EDMX文件,你可以简单地将你的技术表加入资源表的同义词,瞧 - 你就在路上。

更新:请注意,如果您使用的是同义词,则需要对EDMX文件进行一些额外的工作才能使其在Entity Framework中运行。这是一个程序员推出的blog post。以下是她提出的原始stackoverflow问题。

快乐的编码! :)

答案 3 :(得分:0)

您可以创建视图或存储过程,然后您的sql语句可以进行跨数据库查询,只需确保您的凭据可以同时在两个数据库上使用DML或DDL。否则,请尝试使用嵌套的using实体,以确保当您不在using语句中声明db实体时,不会出现linq错误。