Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/336.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/linq/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 使用LINQ从Microsoft CRM检索数据时出现异常行为_C#_Linq_Dynamics Crm 2011_Microsoft Dynamics - Fatal编程技术网

C# 使用LINQ从Microsoft CRM检索数据时出现异常行为

C# 使用LINQ从Microsoft CRM检索数据时出现异常行为,c#,linq,dynamics-crm-2011,microsoft-dynamics,C#,Linq,Dynamics Crm 2011,Microsoft Dynamics,我在使用LINQ访问联系人实体时遇到问题 我有以下两个功能 如果我运行第一个函数,然后调用第二个函数,那么在第二个查询中,我似乎缺少很多字段。比如firstname和lastname没有出现。它们只是显示为空值。如果我自己运行第二个函数,我将获得正确的数据。两次运行中正确显示的字段只有Id、ContactId和new_username 如果我自己运行第二个函数,我将获得正确的数据 知道我做错了什么吗 非常感谢 下面是两个函数 public List<String> GetCo

我在使用LINQ访问联系人实体时遇到问题

我有以下两个功能

如果我运行第一个函数,然后调用第二个函数,那么在第二个查询中,我似乎缺少很多字段。比如firstname和lastname没有出现。它们只是显示为空值。如果我自己运行第二个函数,我将获得正确的数据。两次运行中正确显示的字段只有Id、ContactId和new_username

如果我自己运行第二个函数,我将获得正确的数据

知道我做错了什么吗

非常感谢

下面是两个函数

    public List<String> GetContactsUsernameOnly()
    {
        IQueryable<String> _records = from _contactSet in _flinsafeContext.ContactSet
                                       where
                                           _contactSet.new_FAN == "username"
                                       orderby _contactSet.new_username
                                       select _contactSet.new_username;

        return _records.ToList();
    }

    public List<Contact> GetContacts()
    {
        IQueryable<Contact> _records = from _contactSet in _flinsafeContext.ContactSet
                                       where
                                           _contactSet.new_FAN == "my-username-here"
                                       orderby _contactSet.new_username
                                       select _contactSet;

        return _records.ToList();
    }
public List GetContactsUsernameOnly()
{
IQueryable\u records=来自\u flinsafeContext.contactSet中的\u contactSet
哪里
_contactSet.new_FAN==“用户名”
orderby\u contactSet.new\u用户名
选择_contactSet.new_username;
return_records.ToList();
}
公共列表GetContacts()
{
IQueryable\u records=来自\u flinsafeContext.contactSet中的\u contactSet
哪里
_contactSet.new_FAN==“我的用户名在这里”
orderby\u contactSet.new\u用户名
选择_contactSet;
return_records.ToList();
}

这是因为在调用这两种方法时,您正在重用相同的CRM上下文(在您的情况下是\u\safecontext)

上下文所做的是缓存记录,因此第一种方法是返回联系人,但只返回新的\u用户名字段

第二个方法希望返回整个记录,但是当在第一个记录之后调用它时,该记录已经存在于上下文中,因此它只返回该记录,尽管只填充了一个字段。延迟加载尚未填充的字段是不够聪明的。如果首先调用此方法,则它在上下文中不存在,因此将返回整个记录

有两种方法可以解决这个问题:

1) 不要重复使用crmcontext。相反,在基于singleton IOrganizationService的每个方法中创建一个新的

2) 在您的上下文中有一个ClearChanges()方法,这意味着您下次执行查询时,它将返回到CRM并获取您选择的字段。这还将清除所有未保存的创建/更新/删除等,因此您必须小心上下文处于什么状态

另外,创建一个新的CRM上下文并不是一个密集的操作,所以传递上下文并重用它们通常是不值得的。创建最慢的底层组织服务


这种行为可能非常痛苦,因为返回整个记录的效率非常低,速度也非常慢,因此您希望只为每个查询选择所需的字段

这是因为在调用这两个方法时,您正在重用相同的CRM上下文(在您的案例中是\u\safecontext)

上下文所做的是缓存记录,因此第一种方法是返回联系人,但只返回新的\u用户名字段

第二个方法希望返回整个记录,但是当在第一个记录之后调用它时,该记录已经存在于上下文中,因此它只返回该记录,尽管只填充了一个字段。延迟加载尚未填充的字段是不够聪明的。如果首先调用此方法,则它在上下文中不存在,因此将返回整个记录

有两种方法可以解决这个问题:

1) 不要重复使用crmcontext。相反,在基于singleton IOrganizationService的每个方法中创建一个新的

2) 在您的上下文中有一个ClearChanges()方法,这意味着您下次执行查询时,它将返回到CRM并获取您选择的字段。这还将清除所有未保存的创建/更新/删除等,因此您必须小心上下文处于什么状态

另外,创建一个新的CRM上下文并不是一个密集的操作,所以传递上下文并重用它们通常是不值得的。创建最慢的底层组织服务


这种行为可能非常痛苦,因为返回整个记录的效率非常低,速度也非常慢,因此您希望只为每个查询选择所需的字段

下面是您如何返回所需字段的方法:

IEnumerable<ptl_billpayerapportionment> bpas = context.ptl_billpayerapportionmentSet
.Where(bm => bm.ptl_bill.Id == billId)
.Select(bm => new ptl_billpayerapportionment()
{
    Id = bm.Id,
    ptl_contact = bm.ptl_contact
})
IEnumerable bpas=context.ptl\u BillPayerReportionSet
.其中(bm=>bm.ptl_bill.Id==billId)
.选择(bm=>new ptl_BillPayerReportionment()
{
Id=bm.Id,
ptl_触点=bm.ptl_触点
})
这将确保针对上下文执行更小的sql语句,因为Id和ptl_contact是唯一返回的两个字段。但是正如Ben在上面所说的,在同一上下文中对同一实体的进一步检索将为初始select中未包含的字段返回空值(根据OP的问题)


对于额外积分,使用IEnumerable并创建一个新的轻量级实体可以让您访问常用的LINQ方法,例如.Any(),.Sum()等。显然,CRM SDK不喜欢对var数据集使用它们。

下面是您返回所需字段的方法:

IEnumerable<ptl_billpayerapportionment> bpas = context.ptl_billpayerapportionmentSet
.Where(bm => bm.ptl_bill.Id == billId)
.Select(bm => new ptl_billpayerapportionment()
{
    Id = bm.Id,
    ptl_contact = bm.ptl_contact
})
IEnumerable bpas=context.ptl\u BillPayerReportionSet
.其中(bm=>bm.ptl_bill.Id==billId)
.选择(bm=>new ptl_BillPayerReportionment()
{
Id=bm.Id,
ptl_触点=bm.ptl_触点
})
这将确保针对上下文执行更小的sql语句,因为Id和ptl_contact是唯一返回的两个字段。但是正如Ben在上面所说的,在同一上下文中对同一实体的进一步检索将为初始select中未包含的字段返回空值(根据OP的问题)

为了