我注意到CRM主持人David Jennaway在technet论坛上表示,您不能使用LINQ在CRM 2011中更新/创建记录请参阅此处http://social.microsoft.com/Forums/en-IE/crmdevelopment/thread/682a7be2-1c07-497e-8f58-cea55c298062
但我看到了一些线索,让它看起来似乎应该起作用。这是我的尝试,但没有成功。有什么想法为什么不呢?
IOrganizationServiceFactory serviceFactory = (IOrganizationServiceFactory)serviceProvider.GetService(typeof(IOrganizationServiceFactory));
IOrganizationService service = serviceFactory.CreateOrganizationService(context.UserId);
OrganizationServiceContext orgContext = new OrganizationServiceContext(service);
EntityState state = new EntityState();
state = EntityState.Changed;
var counter = from c in orgContext.CreateQuery<pcx_entitycounter>()
where c.pcx_name.Contains("pcx_candidate")
select new pcx_entitycounter
{Id = c.Id,
pcx_name = c.pcx_name, pcx_Sequence = c.pcx_Sequence, pcx_Prefix = c.pcx_Prefix
};
foreach (var c in counter)
{
string prefix = c.pcx_Prefix.ToString(); ;
string sequence = c.pcx_Sequence.ToString();
c.pcx_Sequence = c.pcx_Sequence + 1;
c.EntityState = state;
**service.Update(c);** //FAILS HERE
}
根据我的经验,从上下文中检索实体、更新实体,然后使用服务保存更改是很困难的,甚至是不可能的。弄清楚它让我头疼!
由于检索代码使用来自Context的查询,因此所有这些实体都应附加到Context,并跟踪它们的状态。因此,您需要使用Context的方法进行更新:
foreach (var c in counter) {
string prefix = c.pcx_Prefix.ToString(); ;
string sequence = c.pcx_Sequence.ToString();
c.pcx_Sequence = c.pcx_Sequence + 1;
// Use the Context to save changes
orgContext.UpdateObject(c);
orgContext.SaveChanges();
}
由于我的许多代码将根据情况以不同的方式(即服务或上下文)检索实体,因此我开发了一个简单的方法,知道如何正确更新实体。为了扩展您的示例,您可能有一个更新方法,看起来像:
public void UpdatePcxEntityCounter(pcx_entitycounter c) {
if (!orgContext.IsAttached(c)) {
service.Update(c);
}
else {
orgContext.UpdateObject(c);
orgContext.SaveChanges();
}
}
这假设orgContext
和service
在高于该方法的范围内都可用。否则,必须将它们作为附加参数传递。
在没有发现困难的情况下,很难辨别问题是什么,但您是否尝试过使用orgContext.UpdateObject(c);在执行更新步骤之前?此外,也不确定为什么要将前缀和序列分配给循环中的局部变量,因为它们似乎没有被使用。您可能会得到一个SOAP异常或用于分配不起作用的值的东西。你有在实体上注册的插件吗?
有关可能的解决方案,请参阅以下链接-
如何在插件中使用LINQ更新CRM 2011实体?
http://social.microsoft.com/Forums/en-US/crmdevelopment/thread/7ae89b3b-6eca-4876-9513-042739fa432a