使用Telerik ORM,当连接来自不同上下文的2个表时抛出错误
本文关键字:2个 上下文 错误 出错 ORM Telerik 连接 使用 | 更新日期: 2023-09-27 18:09:40
我试图在LINQ中使用连接来连接到不同上下文中的表。当我在同一上下文中连接两个表时,它可以工作,所以我相信我的连接是OK的,但是当我连接两个处于不同上下文中的表时,我得到一个错误。是否有可能连接来自不同上下文的两个表?
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using RmmDal.Contexts.RmmCrm;
using RmmDal.Contexts.LMS;
using Telerik.OpenAccess;
namespace ConsoleApplication_Test_ORM
{
class Program
{
static void Main(string[] args)
{
RmmDal.Contexts.RmmCrm.RmmCrmContext dbContextRmmCrm = new RmmDal.Contexts.RmmCrm.RmmCrmContext();
RmmDal.Contexts.LMS.LMS_000Context dbContextLMS = new RmmDal.Contexts.LMS.LMS_000Context();
try
{
Guid LeadId = new Guid("9EF2874C-D37F-4503-A3D8-1A73774BFBBC");
//This doesn't work, I think because it is using 2 seperate Contexts
//I need this to work
var Leads1 = from lo in dbContextLMS.Tbl_Loan_Appls
join la in dbContextRmmCrm.LeadApplications
on lo.Appl_No equals la.Appl_No
select new
{
SSN = lo.Cust_SSN,
TDCCustID = lo.Cust_ID
};
//This works, I think because they are the same context
var Leads2 = from lo in dbContextLMS.Tbl_Loan_Appls
join la in dbContextLMS.Tbl_Customers
on lo.Cust_ID equals la.Cust_ID
select new
{
SSN = lo.Cust_SSN,
TDCCustID = lo.Cust_ID
};
var something = Leads1.FirstOrDefault();
var something2 = Leads1.FirstOrDefault();
}
catch (Exception ex)
{
throw ex;
}
}
}
}
下面是抛出的错误:
An exception occured during the execution of 'Extent<RmmDal.Tbl_Loan_Appl>().Join(Extent<RmmDal.Contexts.RmmCrm.LeadApplication>(), lo => lo.Appl_No, la => la.Appl_No, (lo, la) => new <>f__AnonymousType0`2(SSN = lo.Cust_SSN, TDCCustID = lo.Cust_ID))'. Failure: Object reference not set to an instance of an object.
See InnerException for more details.
Complete Expression:
.Call System.Linq.Queryable.Join(
.Constant<Telerik.OpenAccess.Query.ExtentQueryImpl`1[RmmDal.Tbl_Loan_Appl]>(Extent<RmmDal.Tbl_Loan_Appl>()),
.Constant<Telerik.OpenAccess.Query.ExtentQueryImpl`1[RmmDal.Contexts.RmmCrm.LeadApplication]>(Extent<RmmDal.Contexts.RmmCrm.LeadApplication>()),
'(.Lambda #Lambda1<System.Func`2[RmmDal.Tbl_Loan_Appl,System.Int64]>),
'(.Lambda #Lambda2<System.Func`2[RmmDal.Contexts.RmmCrm.LeadApplication,System.Int64]>),
'(.Lambda #Lambda3<System.Func`3[RmmDal.Tbl_Loan_Appl,RmmDal.Contexts.RmmCrm.LeadApplication,<>f__AnonymousType0`2[System.String,System.Int64]]>))
.Lambda #Lambda1<System.Func`2[RmmDal.Tbl_Loan_Appl,System.Int64]>(RmmDal.Tbl_Loan_Appl $lo) {
$lo.Appl_No
}
.Lambda #Lambda2<System.Func`2[RmmDal.Contexts.RmmCrm.LeadApplication,System.Int64]>(RmmDal.Contexts.RmmCrm.LeadApplication $la)
{
$la.Appl_No
}
.Lambda #Lambda3<System.Func`3[RmmDal.Tbl_Loan_Appl,RmmDal.Contexts.RmmCrm.LeadApplication,<>f__AnonymousType0`2[System.String,System.Int64]]>(
RmmDal.Tbl_Loan_Appl $lo,
RmmDal.Contexts.RmmCrm.LeadApplication $la) {
.New <>f__AnonymousType0`2[System.String,System.Int64](
$lo.Cust_SSN,
$lo.Cust_ID)
}
在设计上不支持连接来自两个不同上下文的实体。
连接这些数据集的唯一方法是使用内存连接,如建议使用Trust me - I'm a Doctor。
蛮力方法可以只是在两个上下文端点上调用.ToList()
,然后在连接查询中使用内存中的数据。这将是低效和有问题的,因为大量数据将放在内存中,并且可能在执行连接后被丢弃,因此预期会出现非常糟糕的性能。
一种更有效的方法是从左侧遍历结果,并使用.Contains()
方法从右侧过滤出"连接"的记录。
// Load a small fragment of leads in memory
var Leads1 = dbContextLMS.Tbl_Loan_Appls.Skip(0).Take(10).ToList();
// find the IDs
var leadIds = Leads1.Select(l= > l.Appl_No);
// filter out only the matching applications
var applications = dbContextRmmCrm.LeadApplications
.Where(a=> leadIds.Contains(a.Appli_No))
.Select(a=> new { SSN = a.Cust_SSN, TDCCustID = а.Cust_ID });
分页是必需的,以便处理一小部分数据,因此.Contains()
子句可以安全地转换为SQL IN clause
。您必须在循环中包装代码片段,并相应地增加Skip()
和Take()
参数。