使用CRM 2011 SDK(v5.0.10)我遇到了少数Lookup字段的问题,其中没有填充目标,我希望有人可以帮助我确定确定这些中引用实体的最佳方法例。
具体来说,我正在使用此调用检索实体,属性和关系元数据:
var entityRequest = new RetrieveAllEntitiesRequest
{
RetrieveAsIfPublished = true,
EntityFilters = EntityFilters.Entity | EntityFilters.Attributes | EntityFilters.Relationships
};
var entityResponse = (RetrieveAllEntitiesResponse)_organizationService.Execute(entityRequest);
return entityResponse.EntityMetadata.ToList();
稍后,在使用从该调用返回的EntityMetadata对象时,我检查Attributes集合,对于LookupAttributeMetadata对象,我尝试使用LookupAttributeMetadata对象的Targets属性确定查找引用的实体。
但是,在某些情况下,LookupAttributeMetadata对象具有空的Targets集合。例如,Campaign活动(逻辑名称:campaignactivity)实体将Service字段(逻辑名称:serviced)定义为Lookup字段,但LookupAttributeMetadata对象上的Targets属性为空。
当我查看实体的Web UI Customizations屏幕并打开Service字段时,在Type部分下显示Type:Lookup,Target Record Type:Account,Relationship Name:campaignactivity_account。
这些信息来自哪里?
另请注意:广告系列活动或帐户实体上没有名为“campaignactivity_account”的关系。
更新:
我正在运行Dynamics CRM 2011 Rollup 8的库存安装(虽然我也在Rolloup 7上看到了这一点)。虽然“广告系列活动”是我在我的示例中使用的字段,但总共有14个问题,如下所示。我正在寻找一个通用的解决方案(针对每个解决方案的一次性解决方案),以避免在我的代码中使用一堆if (entityName=="rollupfield" && fieldName=="organizationid")...
逻辑,因为我正在使用的实体和字段由用户选择运行时间,我不一定提前知道我将要交给谁。
更新: 以下控制台应用程序可用于重现该问题。
//Requires the following Referenses:
// Microsoft.CSharp
// Microsoft.IdentityModel
// Microsoft.xrm.sdk
// System
// System.Core
// System.Data
// System.Runtime.Serialization
// System.ServiceModel
using System;
using System.Linq;
using System.Net;
using Microsoft.Xrm.Sdk;
using Microsoft.Xrm.Sdk.Client;
using Microsoft.Xrm.Sdk.Messages;
using Microsoft.Xrm.Sdk.Metadata;
namespace TargetlessLookupsPOC
{
internal static class Program
{
private const string OrganizationServiceURL =
"http://dynamicscrm1/DynamicsCRM1/XRMServices/2011/Organization.svc";
private static void Main(string[] args)
{
Console.WriteLine("====== Authenticating ");
var organizationServiceMngt =
ServiceConfigurationFactory.CreateManagement<IOrganizationService>(new Uri(OrganizationServiceURL));
var authCred = new AuthenticationCredentials();
authCred.ClientCredentials.Windows.ClientCredential = new NetworkCredential();
IOrganizationService orgProxy = new OrganizationServiceProxy(organizationServiceMngt,
authCred.ClientCredentials);
Console.WriteLine("====== Fetching All Entity Metadata ");
var entityRequest = new RetrieveAllEntitiesRequest
{
RetrieveAsIfPublished = true,
EntityFilters = EntityFilters.Entity | EntityFilters.Attributes | EntityFilters.Relationships
};
var entityResponse = (RetrieveAllEntitiesResponse) orgProxy.Execute(entityRequest);
Console.WriteLine("====== Searching For Targetless Lookups ");
foreach (var ent in entityResponse.EntityMetadata)
{
foreach (var field in ent.Attributes
.OfType<LookupAttributeMetadata>()
.Where(lookup => !lookup.Targets.Any()))
{
Console.WriteLine("Entity: {0} ({1}), Field: {2} ({3}) (type: {4}) is targetless",
ent.DisplayName.LabelText(), ent.LogicalName,
field.DisplayName.LabelText(), field.LogicalName,
field.AttributeType);
}
}
Console.WriteLine("=========================== Done");
Console.WriteLine("** Press any key to continue **");
Console.ReadKey();
}
public static string LabelText(this Label label)
{
return (label != null && label.UserLocalizedLabel != null)
? label.UserLocalizedLabel.Label
: "<no label>";
}
}
}
答案 0 :(得分:1)
您是否尝试过使用RetrieveRelationshipRequest消息?
这将返回一个RetrieveRelationshipResponse类,该类具有RelationshipMetadata属性,而该属性又取决于关系,它将是OneToManyRelationshipMetadata或ManyToManyRelationshipMetadata。在OneToManyRelationshipMetadata类的属性中,您将找到RendixAttribute和ReferencedAttribute属性,这是您想要的。
答案 1 :(得分:0)
我在这里无法理解这个问题。具有查找字段的实体可能具有也可能不具有目标实体。当然,我检查了其中一些,但没有一个引用的查找是必需的。对于timezonerule实体,organizationid始终为NULL。根据你的更新,我想你可能得出了同样的结论。
当然,我主要使用Fetch,但我倾向于遍历属性并基于属性类型并将每个属性添加到Dictionary对象中。字典对象包含在List(即List<Dictionary<string, object>>
)
这样我就可以传递一个通用的Fetch语句,并获得填充属性的干净iList。对于查找,您还可以附加“_name”属性以获取显示值。