我正在使用早期绑定在联系人实体上编写PostUpdate插件
不幸的是,所有应该代表1:x关系的属性都是空的
代码非常简单:
* CRMcontext是通过CrmSvcUtil.exe生成的文件,
* service是LocalPluginContext的IOrganizationService:
using ( var serviceContext = new CRMcontext(service) )
{
// This works fine
var contact = serviceContext.CreateQuery<Contact>().First(c => c.Id == context.PrimaryEntityId);
// why is currency null after this line?! (and yes, it's set in the entity)
var currency = contact.transactioncurrency_contact;
}
我按照此示例(最后一个代码段):http://msdn.microsoft.com/en-us/library/gg695791.aspx
感谢您的帮助!
编辑:
/// <summary>
/// N:1 transactioncurrency_contact
/// </summary>
[Microsoft.Xrm.Sdk.AttributeLogicalNameAttribute("transactioncurrencyid")]
[Microsoft.Xrm.Sdk.RelationshipSchemaNameAttribute("transactioncurrency_contact")]
public TransactionCurrency transactioncurrency_contact
{
get
{
return this.GetRelatedEntity<TransactionCurrency>("transactioncurrency_contact", null);
}
set
{
this.OnPropertyChanging("transactioncurrency_contact");
this.SetRelatedEntity<TransactionCurrency>("transactioncurrency_contact", null, value);
this.OnPropertyChanged("transactioncurrency_contact");
}
}
答案 0 :(得分:2)
CRM不会自动加载相关的实体属性。您需要在每个延迟加载的属性上调用LoadProperty。
并且LameCoder不正确,LINQ to CRM不会生成Fetch Xml,而是QueryExpressions
,这就是为什么它仅限于QueryExpressions
拥有的任何功能。
GetRelatedEntity方法定义如下:
protected virtual IEnumerable<TEntity> GetRelatedEntities<TEntity>(string relationshipSchemaName, EntityRole? primaryEntityRole) where TEntity : Entity
{
if (string.IsNullOrWhiteSpace(relationshipSchemaName))
throw new ArgumentNullException("relationshipSchemaName");
Relationship key = new Relationship(relationshipSchemaName)
{
PrimaryEntityRole = primaryEntityRole
};
if (!this.RelatedEntities.Contains(key))
return (IEnumerable<TEntity>) null;
else
return Enumerable.Cast<TEntity>((IEnumerable) this.RelatedEntities[key].Entities);
}
如果您的早期绑定实体继承自Entity
,那么它所做的只是访问它自己的内部RelatedEntities集合。它无法访问服务器以加载相关属性。
如果您使用CodeGeneration.CodeCustomization生成早期绑定实体,它应该按照您列出的那样工作,因为它将继承自CrmEntity
,它会为您加载关系,因为它会覆盖GetRelatedEntity method使用上下文为你获取它。
答案 1 :(得分:1)
我的理解是LINQ查询只是创建FetchXML,除非你特别要求,否则不会扩展关系。
您应该在LINQ查询中加入以获得所需的关系,但请注意,根据CRM 2013 SDK LINQ查询仅支持内部联接。因此,您将无法找回错过关系的记录。
如果您使用SVC Util生成具有SDK扩展程序集的早期绑定类型(可能难以在插件中使用),则扩展程序具有的Context可以在您访问该属性时自动扩展。有关详细信息,请参阅Microsoft.Xrm.Client.CrmOrganizationServiceContext
类,如果尚未通过调用Attach,则需要将实体附加到上下文。请记住,这只是懒惰地对关系进行查询,因此在场景后面会有多个查询。
如果您想在一个查询中完成所有操作,并且需要LEFT连接,请尝试直接使用FetchXML。
编辑: 另请注意,在您指定的MSDN链接中,该示例试图显示相关实体如何为null,除非您调用LoadProperty。所以你可以简单地调用LoadProperty来加载你需要的东西。
答案 2 :(得分:0)
对于2016年的CRM更新,有些事情发生了变化。您现在应该像Daryl建议的那样使用LoadProperty方法。这会奏效。
我使用CodeGeneration.CodeCustomization来生成早期绑定实体,但不幸的是,CRM 2016 SDK似乎还没有所需的Microsoft.Xrm.Client.CodeGeneration.dll。因此,从2016年更新开始,这种方式不再适用。