【问题标题】:Why are all reference properties null in my CRM plugin?为什么我的 CRM 插件中的所有引用属性都为空?
【发布时间】:2014-01-20 06:42:16
【问题描述】:

我正在使用早期绑定在联系人实体上编写 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;
}

我按照这个例子(最后一个代码sn-p):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");
    }
}

【问题讨论】:

  • GetRelatedEntity 有效吗?
  • GetRelatedEntity 正在被生成的包装器调用(在 get_transactioncurrency_contact 中)并返回 NULL。
  • 你确定在你的代码中被调用了吗?你调试过这个吗?您是否尝试过手动调用 GetRelatedEntity?
  • 是的,它正在被调用 - 我已经从包装代码(由 CrmSvcUtil.exe 生成)中删除了自动生成的标头,并在属性的 getter 中设置了一个断点。
  • 发布您的 transactioncurrency_contact 属性代码。

标签: c# plugins dynamics-crm-2011 crm dynamics-crm-2013


【解决方案1】:

CRM 不会自动加载相关的实体属性。您需要在每个延迟加载的属性上调用 LoadProperty

而且 LameCoder 不正确,LINQ to CRM 不会生成 Fetch Xml,而是 QueryExpressions,这就是为什么它仅限于 QueryExpressions 拥有的任何能力。

编辑 1 - 为什么这不能像 MSDN 文章中的最后一个示例那样隐式工作?

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,那么它唯一要做的就是访问它自己的内部相关实体集合。它没有做任何事情来访问服务器以加载相关属性。

如果您使用CodeGeneration.CodeCustomization 生成早期绑定实体,它应该可以按照您列出的那样工作,因为它将继承自CrmEntity,它将为您加载关系,因为它会覆盖 GetRelatedEntity 方法使用上下文给你拿来。

【讨论】:

  • 奇怪的事情:需要在延迟加载的属性上调用 LoadProperty?
  • @Sascha 对我来说很有意义。您必须在 Context 上调用它,以便它可以为您加载它。您不想为检索到的每个实体加载所有相关属性。
  • 不能隐式调用LoadProperty? (就像链接的 msdn 页面的最后一个示例一样)
  • SDK 扩展有一个覆盖 GetRelatedEntities 的子类,它能够进行延迟加载。所以这取决于你的上下文的实现
  • Microsoft 使它令人困惑,因为 SDK 扩展继承自 SDK 中的相同类并且具有非常不同的行为。轻微违反 Liskov Subtituation 原则,但在阅读来自不同来源的文档时足以引起一些混乱。
【解决方案2】:

我的理解是 LINQ 查询只是要创建 FetchXML,除非您特别请求,否则不会扩展关系。

您应该在 LINQ 查询中进行联接以获得所需的关系,但请注意,根据 CRM 2013 SDK LINQ 查询仅支持内部联接。因此,您将无法取回缺少关系的记录。

如果您使用 SVC Util 通过 SDK 扩展程序集(可能难以在插件中使用)生成早期绑定类型,则扩展具有的上下文能够在您访问属性时自动扩展。有关详细信息,请参阅Microsoft.Xrm.Client.CrmOrganizationServiceContext 类,如果尚未通过调用 Attach,您需要将实体附加到上下文。请记住,这只是懒惰地对关系进行查询,因此会在后台执行多个查询。

如果您想在一个查询中完成所有操作,并且需要 LEFT 连接,请尝试直接使用 FetchXML。

编辑: 另请注意,在您指定的 MSDN 链接中,该示例试图显示相关实体如何为空,除非您调用 LoadProperty。所以你可以简单地调用 LoadProperty 来加载你需要的东西。

【讨论】:

  • 抱歉,这个问题可能很愚蠢,但是:示例中说“.. 隐式调用 LoadProperty..”。 LoadProperty 在哪里隐式调用?
  • 如果您查看 MSDN 示例,它被明确调用。如果您使用的是 Microsoft.Xrm.Client.CrmOrganizationServiceContext,它不会使用 LoadProperty,但在 GetRelatedEntity 的覆盖中有另一种机制,可以延迟加载。
  • CRM 2013 现在可以进行外部联接了! LINQ 查询或 QueryExpressions 不支持它是正确的,但 FetchXML 支持它。非常适合报告! dynamicscrmusualsuspect.blogspot.com/2013/10/…
【解决方案3】:

对于 CRM 的 2016 年更新,一些事情发生了变化。您现在应该按照 Daryl 的建议使用 LoadProperty 方法。这将起作用。

我使用 CodeGeneration.CodeCustomization 生成早期绑定实体,但不幸的是,CRM 2016 SDK 似乎不再具有所需的 Microsoft.Xrm.Client.CodeGeneration.dll。所以这种方式在 2016 年更新后不再适用。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-03-13
    • 1970-01-01
    • 1970-01-01
    • 2020-02-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多