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