【问题标题】:Return IQueryable<T> from another class instance从另一个类实例返回 IQueryable<T>
【发布时间】:2016-01-08 00:20:03
【问题描述】:

我想要完成的是创建一个返回通用IQueryable&lt;T&gt; 的基类,并使用来自另一个类实例的IQueryable 进行进一步过滤。 埃斯。 基类返回所有记录,调用类从那里过滤。

这是基类,getDealer_query 是返回主IQueryable的方法

 public class Dealer
 {
    public DAL.DBConn_Nav db = null;
    public G4.Elements.Identity oIdentity = null;

    public Dealer()
    {
        oIdentity = new G4.Elements.Identity();
        oIdentity.read();
    }

    public IQueryable<outerViewModel.NavisionDAL.vmDealer> getDealer_query()
    {
        IQueryable<vmDealer> dealer = (from d in db.DENTALICA_S_P_A__Customer
                                       select new vmDealer()
                                       {
                                           idDealer = d.No_,
                                           name = d.Name + (d.Name_2.Length > 0 ? " " + d.Name_2 : ""),
                                           address = d.Address + (d.Address_2.Length > 0 ? " " + d.Address_2 : ""),
                                           city = d.City,
                                           zip = d.Post_Code,
                                           county = d.County,
                                           email = d.E_Mail,
                                           phone = d.Phone_No_,
                                           fax = d.Fax_No_,
                                           vat = d.VAT_Registration_No_,
                                           ssn = d.Fiscal_Code,
                                           businessAreaCode = d.Business_Area_Code,
                                           businessZoneCode = d.Business_Zone_Code,
                                           clienteDiretto = (d.Cliente_Diretto == (byte)1 ? true : false),
                                           aggancioOrdiniWeb = (d.Deposito_Agg__Ordini_Web == (byte)1 ? true : false),
                                           aggancioOrdiniG4 = (d.Deposito_Agg__Ordini_G4 == (byte)1 ? true : false),
                                           notUse = (d.Not_Use == (byte)1 ? true : false),
                                           blocked = d.Blocked,
                                           shipmentMethodCode = d.Shipment_Method_Code,
                                           paymentTermsCode = d.Payment_Terms_Code,
                                           paymentMethodCode = d.Payment_Method_Code,
                                           shippingAgentCode = d.Shipping_Agent_Code,
                                           customerPriceGroup = d.Customer_Price_Group,
                                           customerDiscountGroup = d.Customer_Disc__Group,
                                           identificaCliente = d.Identifica_Cliente

                                       });
        return dealer;
    }

这是另一个类Customer,它从Dealer 的实例调用方法并最终列出数据。

public class Customer
{
    G4.Elements.Identity oIdentity = null;
    DAL.DBConn_Nav navDB = null;

    public Customer()
    {
        //oIdentity = new G4.Elements.Identity();
        //oIdentity.read();
    }

    ///// <summary>
    ///// Recupera l'elenco dei clienti Navision (i Depositi pr G4) visibili ad un particolare utente
    ///// </summary>
    ///// <returns></returns>
    public IQueryable<outerViewModel.NavisionDAL.vmDealer> getCustomerForOperator_query()
    {
        string idOperator = !string.IsNullOrEmpty(oIdentity.selectedId) ? oIdentity.selectedId : oIdentity.id;

        using (navDB = new DAL.DBConn_Nav()) {
            G4.Models.NavisionDAL.Dealer oD = new G4.Models.NavisionDAL.Dealer();
            // Tutti i Clienti
            IQueryable<outerViewModel.NavisionDAL.vmDealer> allCustomerList_query = oD.getDealer_query();
            IQueryable<outerViewModel.NavisionDAL.vmDealer> customerForOperator_query = (from c in allCustomerList_query                                                                                join cForOp in navDB.DENTALICA_S_P_A__SalesPerson_Customer on c.idDealer equals cForOp.Customer_No_
                                                                                         where cForOp.Salesperson_Code.Equals(idOperator)
                                                                                         && cForOp.Starting_Date < DateTime.Now
                                                                                         && (cForOp.Ending_Date.Equals(new DateTime(1753, 1, 1)) || cForOp.Ending_Date > DateTime.Now)
                                                                                         && c.notUse.Equals(false)
                                                                                      select c).Distinct();

            return customerForOperator_query;
        }
    }

    public List<G4.outerViewModel.NavisionDAL.vmDealer> getCustomerForOperator()
    {
        using (navDB = new DAL.DBConn_Nav())
        {
            G4.Models.NavisionDAL.Dealer oD = new G4.Models.NavisionDAL.Dealer();
            return getCustomerForOperator_query().ToList();
        }
    }

但它不起作用!我得到一个通用的“对象未设置为实例......”。

即使我尝试调试也无济于事,因为光标不会停止。

为了让它工作,我必须从 Customer 继承 Dealer 类,但这不是我想要的。

我想我在这里遗漏了一些基本的东西。

有什么想法吗?

编辑 - 简化示例 我正在添加相同代码的简化示例。

public class Dealer1
{

    public DAL.DBConn_Nav db = null;

    public Dealer1() { 

    }

    public IQueryable<outerViewModel.NavisionDAL.vmDealer> getDealer_query()
    {

        IQueryable<vmDealer> dealer = (from d in db.DENTALICA_S_P_A__Customer

                                       select new vmDealer()
                                       {
                                           idDealer = d.No_,
                                           name = d.Name + (d.Name_2.Length > 0 ? " " + d.Name_2 : "")

                                       });

        return dealer;

    }
}


 public class Customer1
{

    public DAL.DBConn_Nav db = null;

    public Customer1()
    {

    }

    public IQueryable<outerViewModel.NavisionDAL.vmDealer> getCustomerForOperator_query()
    {

        // All customers
        G4.Models.NavisionDAL.Dealer1 oD = new G4.Models.NavisionDAL.Dealer1();

        IQueryable<outerViewModel.NavisionDAL.vmDealer> allCustomerList_query = oD.getDealer_query().Where(i => i.name.StartsWith("AAA"));

        return allCustomerList_query;

    }

    public List<G4.outerViewModel.NavisionDAL.vmDealer> getCustomerForOperator()
    {

        using (db = new DAL.DBConn_Nav())
        {
            return getCustomerForOperator_query().ToList();
        }


    }
}

【问题讨论】:

    标签: c# .net entity-framework linq iqueryable


    【解决方案1】:

    在您的班级Dealer 中没有设置db 的实例。

    public DAL.DBConn_Nav db = null;
    

    因此,即使在 Customer 中调用 using (navDB = new DAL.DBConn_Nav()),您也不会将 navDB 传递给 Dealer,因此当您调用 getDealer_query() 时,您会收到空引用异常。


    根据您的简化示例,我会推荐以下代码:

    public class Dealer1
    {
        internal IQueryable<vmDealer> getDealer_query(DAL.DBConn_Nav db)
        {
            return
                from d in db.DENTALICA_S_P_A__Customer
                select new vmDealer()
                {
                    idDealer = d.No_,
                    name = String.Join(" ", d.Name, d.Name_2)
                };
        }
    }
    
    public class Customer1
    {
        internal IQueryable<vmDealer> getCustomerForOperator_query(DAL.DBConn_Nav db)
        {
            return new Dealer1().getDealer_query(db).Where(i => i.name.StartsWith("AAA"));
        }
    
        public List<vmDealer> getCustomerForOperator()
        {
            using (var db = new DAL.DBConn_Nav())
            {
                return getCustomerForOperator_query(db).ToList();
            }
        }
    }
    

    这清楚地允许您分离责任,但它使您可以完全控制 db 实例 - 您需要在完成后处理它。

    【讨论】:

    • 我想您已经发现了问题所在,但我不知道如何将其转化为工作男女同校。我已将相同代码的简化示例添加到 2 个新类 Dealer1 和 Customer1 中。我应该如何处理 DAL.DBConn_Nav 数据库以使其正常工作?
    • 太棒了!它工作得很好,这就是我想要的。谢谢
    【解决方案2】:

    allCustomerList_query 为空不应该是有原因的。

    为了确认getDealer_query 方法中的 linq 语句正在工作,我会将您的代码更改为如下所示:

            List<outerViewModel.NavisionDAL.vmDealer> something = new List<outerViewModel.NavisionDAL.vmDealer>();
            IQueryable<outerViewModel.NavisionDAL.vmDealer> test = something.AsQueryable();
            return test;
    

    无论如何,为了防止对象引用错误,您需要保证返回一个实例,从代码示例中我实际上无法判断。

    getDealer_query 方法中不能得到一个断点来停止,这很奇怪。您是否在运行多个线程的测试中运行它?可能发生的情况是另一个线程引发了未处理的异常,因此整个测试停止。尝试在getDealer_query 中的return dealer 之前和G4.Models.NavisionDAL.Dealer oD = new G4.Models.NavisionDAL.Dealer(); 上放置断点。假设没有其他线程,代码必须在其中一个上停止。

    最后一点,查看代码,我没有看到db 是在哪里实例化的。如果它没有被实例化,你会在这一行得到一个对象引用错误:

        `IQueryable<vmDealer> dealer = (from d in db.DENTALICA_S_P_A__Customer`
    

    【讨论】:

      猜你喜欢
      • 2010-10-17
      • 1970-01-01
      • 1970-01-01
      • 2021-02-20
      • 2018-12-08
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多