使用Telerik ORM时,从不同的上下文连接2个表时会抛出错误

时间:2013-04-16 13:53:40

标签: c# .net linq orm telerik

我是Telerik ORM的新手,所以请光临我。我也是LINQ的半新手,虽然我刚读过“Wrox Professional LINQ”一书,所以我觉得很舒服。

我试图在LINQ中使用连接来连接到不同上下文中的表。当我在相同的上下文中连接两个表时它可以工作,所以我相信我的连接是可以的。但是当我加入两个处于不同上下文中的表时,我得到一个错误。是否可以连接来自不同上下文的两个表。请帮助我疯了。

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)

}

1 个答案:

答案 0 :(得分:1)

设计不支持加入来自两个不同背景的实体 加入这些数据集的唯一方法是使用建议的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()参数。