【问题标题】:Linq Query returns object reference exceptionLinq 查询返回对象引用异常
【发布时间】:2012-02-12 15:26:52
【问题描述】:

我查看了一些关于此异常在 Linq 代码中弹出的帖子,但没有任何帮助。我知道这意味着我在某处指的是空值,但我已经设置了一个 if 语句来防止错误。

我想要做的是查询 CRM 数据库,但每个查询的联系人只返回三条信息。异常发生在 foreach 行。这是我的代码(嗯,并不是我的全部):

class Program
{
    private static List<account> accs = new List<account>();
    private static List<CrmContact> cnts = new List<CrmContact>();

    static void Main(string[] args)
    {
        if (!CRMConnectionHelper.Authenticate()) throw new Exception("Authentication on CRM Server was NOT successful.");
        Console.WriteLine("Authentication on CRM Server was successful.");

        GetAllAccounts();
        GetActiveContacts();
        QueryDB();
    }

    private static void QueryDB()
    {
        var m = from c in cnts

                select new
                {
                    acct = c.ParentAccount.name,
                    last = c.Contact.lastname,
                    first = c.Contact.firstname
                };

            List<string> lines = new List<string>();

            try
            {
                foreach (var c in m) **Exception here**
                {
                    if (c != null)
                    {
                        //string sub = c1.first.PadRight(10).Substring(0, 3); // Object ref ex here. 
                        lines.Add(string.Format("{0}\t{1}\t{2}", c.acct, c.last, c.first));
                        Console.WriteLine(c.acct);
                        System.Threading.Thread.Sleep(100);
                    }
                    else
                    {
                        Console.WriteLine("c is null. continuing.");
                        continue;
                    }
                }

                Console.WriteLine("Writing list contents to .txt ...");
                System.IO.File.WriteAllLines(@"C:\Documents and Settings\paldrich\Desktop\lines1.txt", lines.ToArray());
                Console.WriteLine("Finished. Press ENTER to exit.");
                Console.ReadLine();
            }
            catch (Exception ex)
            {
                Console.WriteLine(String.Format("Error: {0}", ex));
            }   
        }

    private static void GetAllAccounts()
    {
        ColumnSet colsAcc = new ColumnSet { Attributes = new string[] { "accountid", "name", "statecode" } };
        QueryExpression accountQuery = new QueryExpression { EntityName = EntityName.account.ToString(), ColumnSet = colsAcc };
        BusinessEntityCollection accounts = CRMConnectionHelper.crmService.RetrieveMultiple(accountQuery);
        Console.WriteLine(String.Format("Total number of accounts {0}", accounts.BusinessEntities.Length));
        for (int i = 0; i < accounts.BusinessEntities.Length; i++) { accs.Add((account)accounts.BusinessEntities[i]); }
    }

    private static void GetActiveContacts()
    {
        try
        {
            ColumnSet cols = new ColumnSet { Attributes = new string[] { "contactid", "parentcustomerid", "firstname", "middlename", "lastname", "suffix", "emailaddress1", "emailaddress2", "emailaddress3", "statecode", "caad_duplicateid" } };
            ConditionExpression condition = new ConditionExpression { AttributeName = "statecode", Operator = ConditionOperator.Equal, Values = new string[] { "Active" } };
            FilterExpression filter = new FilterExpression { FilterOperator = LogicalOperator.And, Conditions = new ConditionExpression[] { condition } };
            QueryExpression contactQuery = new QueryExpression { EntityName = EntityName.contact.ToString(), ColumnSet = cols, Criteria = filter };
            BusinessEntityCollection contacts = CRMConnectionHelper.crmService.RetrieveMultiple(contactQuery); //Exception: server cannot process request
            int qty = contacts.BusinessEntities.Length;
            Console.WriteLine(String.Format("Total number of contacts {0}", qty));
            for (int i = 0; i < qty; i++)
            {

                try
                {
                    contact c = (contact)contacts.BusinessEntities[i];
                    account ac = new account();
                    if (c.parentcustomerid != null)
                    {
                        ac = (account)(from a in accs where a.accountid.Value == c.parentcustomerid.Value select a).FirstOrDefault();
                        cnts.Add(new CrmContact(ac, c));
                    }
                    else
                    {
                        cnts.Add(new CrmContact(null, c));
                    }

                }
                catch (Exception ex)
                {

                    Console.WriteLine(String.Format("GetActiveContacts: Error for i={0} : {1}", i, ex.Message));
                    Console.Read();
                }
            }
        }
        catch (Exception ex)
        {

            Console.WriteLine(String.Format("Exception occured trying to get active contacts: {0}", ex));
            Console.Read();
        }
    }
    }
}

如果您有任何见解,请告诉我。谢谢你。

【问题讨论】:

  • 与您的错误没有直接关系,但如果您要查找的只是联系人是否有主帐户,也无需从联系人中单独查询帐户。当您拉回联系人的查询信息时,“c.parentcustomerid.name”(假设它不为空)应该包含父帐户的名称。

标签: c# linq dynamics-crm-4 crm object-reference


【解决方案1】:

让我们看看这个查询:

var m = from c in cnts
        select new
        {
            acct = c.ParentAccount.name,
            last = c.Contact.lastname,
            first = c.Contact.firstname
        };

从此查询返回的任何元素不会为空。所以你绝对不需要这个:

foreach (var c in m)
{
    if (c != null)

new { ... } 表达式从不返回 null。

但是如果c.ParentAccount 为空或c.Contact 为空,您可以从查询中获取异常。

从您的代码中不清楚可能是哪种情况,但您可以将查询更改为:

var m = from c in cnts
        select new
        {
            acct = c.ParentAccount == null ? "" : c.ParentAccount.name,
            last = c.Contact == null ? "" : c.Contact.lastname,
            first = c.Contact == null ? "" : c.Contact.firstname
        };

也有c 本身在这里为空的可能性 - 如果cnts 包含任何空引用。您可以轻松地忽略所有这些元素:

var m = from c in cnts
        where c != null
        select new
        {
            acct = c.ParentAccount == null ? "" : c.ParentAccount.name,
            last = c.Contact == null ? "" : c.Contact.lastname,
            first = c.Contact == null ? "" : c.Contact.firstname
        };

...但最好确保您的集合没有任何空元素开始。

【讨论】:

  • @Hogan: 不 - Select 永远不会返回 null。
  • @Hogan c.ParentAccount 和 c.Contact 也可能为非空,但 name、lastname 或 firstname 属性为空。
  • @phoog:虽然这是真的,但它不会在指定的点导致异常。
  • @JonSkeet 混乱!我正在查看“此处的对象引用前”这一行。而不是“这里的例外”行。
  • 那是我的错,“object ref ex here”位是旧评论。谢谢你,我要到周二才能测试它,但会告诉你会发生什么......
猜你喜欢
  • 2011-01-25
  • 2012-07-29
  • 2021-07-21
  • 2023-03-31
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-03-31
  • 2015-03-05
相关资源
最近更新 更多