使用 'select new' 将 LINQ 查询转换为 CRM QueryExpression

Translating LINQ query into CRM QueryExpression while using 'select new'

我有以下容器 class:

public class AssetAndItsDepositsContainer
    {
        public jp_asset Asset { get; set; }
        public jp_deposit Deposit { get; set; }
    }

有没有办法采用以下 LINQ 查询:

from a in serviceContext.jp_assetSet
join d in serviceContext.jp_depositsSet on a.Id equals d.jp_assetid.Id
where a.statecode == jp_assetState.Active &&
      a.jp_isonhold = true
select new AssetAndItsDepositsContainer()
{
     Asset = a,
     Deposit = d
})
.ToList();

和"translate"它通过使用QueryExpression? 这是我到目前为止想出的,但我不知道如何模仿 select new 表达式:

QueryExpression query = new QueryExpression(jp_asset.EntityLogicalName);
query.ColumnSet = new ColumnSet(true);

query.Criteria.AddCondition("statecode", ConditionOperator.Equal, (int)jp_assetState.Active);
query.Criteria.AddCondition("jp_isonhold", ConditionOperator.Equal, true);
LinkEntity link = query.AddLink(jp_deposit.EntityLogicalName, "Id", "jp_assetid", JoinOperator.Inner);

// Now what?
var res = service.RetrieveMultiple(query).Entities; // gets only jp_assets

您无法访问整个 LinkEntity,您只能将其属性作为主要 Entity 本身的 AliasedValue 属性进行访问。

我会简单地检索您要查找的第二条记录的 ID 作为 EntityReference 的一部分,然后执行 Retrieve

您实际上可以从链接的实体构建有效的 Entity 对象。唯一的要求是链接实体的主键必须在结果集中可用。

因此,您的代码片段可以像这样扩展:

var query = new QueryExpression(jp_asset.EntityLogicalName);
query.ColumnSet.AllColumns = true;
query.Criteria.AddCondition("statecode", ConditionOperator.Equal, (int)jp_assetState.Active);
query.Criteria.AddCondition("jp_isonhold", ConditionOperator.Equal, true);

LinkEntity link = query.AddLink(jp_deposit.EntityLogicalName, "Id", "jp_assetid", JoinOperator.Inner);
link.EntityAlias = "d";
link.Columns.AddColumns("jp_depositid", "jp_name");

IEnumerable<Entity> deposits = Service.RetrieveMultiple(query).Entities
    .Select(e => new Entity("jp_deposit")
    {
        Id = (Guid)e.GetAttributeValue<AliasedValue>("d.jp_depositid").Value,
        ["jp_name"] = e.GetAttributeValue<AliasedValue>("d.jp_name")?.Value
    });

Note

The example above will only work reliable for inner joins. In the result set the primary key (ID) for the linked entity will always be available. Therefore it is safe to get its value using the .Value syntax. All other attribute values can be retrieved using ?.Value.

For left joins you would need to filter the result set first before performing the Select.