我正在提取营销列表清单。正如我这样做,根据我使用intellisense的检查,这似乎是一次成功的操作。当我查找...Entities[0].Attributes["nick"]
时,我得到一个对象(其中包含正确的数据)。但是我无法以编程方式访问它(相反,我必须通过插件点击一下,以便折叠好东西)。
事实上,我认为实体应该使用下面的代码。根据计算机,问题是它们不是Strings
。它们的类型为Microsoft.Xrm.Sdk.AliasedValue
,我不知道如何访问其中的实际缺口。
new Contact
{
Name = element.Attributes["nick"] as String,
Mail = element.Attributes["mail"] as String
}
Intellisense表示Value
在那里(并且它也是正确的值)但我无法通过键入.Value
来访问它。我怀疑我需要使用“as”或类似的东西,但此刻我被卡住了。任何提示? As
将String
null
提供给我new Contact
{
Name = ((Microsoft.Xrm.Sdk.AliasedValue)result.Entities[0].Attributes["nick"]).Value,
Mail = ((Microsoft.Xrm.Sdk.AliasedValue)result.Entities[0].Attributes["mail"]).Value
}
...
我已经阅读了this article以及其他几个喜欢它和我看到它的方式,我应该能够访问那里所有有趣的东西。我不能......
我注意到以下代码为我提供了我非常想要获取的数据但是这个不能成为专业语法,可以吗?!说真的,它看起来像一个患有多动症和宿醉的高中生试图这样做......
{{1}}
我的意思是,认真 - 这是一段难看的代码......必须有更好的方法!但是,我担心不会因为this discussion似乎也在使用该语法......
答案 0 :(得分:7)
查看documention,Attributes
对象的Entity
属性类型为AttributeCollection
,其派生自DataCollection<string,Object>
。
对于集合中的每个属性,都有一个键/值对。
因此,对于每个密钥(“nick”,“mail”),都有一个对应的object
,它可以是任何.NET类型。你有将对象强制转换为正确的类型(正如你所做的那样)来访问你正在寻找的属性(或者使用反射,这肯定会更加丑陋,或者我认为在C#中4.0 dynamic
type,但在这种情况下,您将失去编译时检查);编译器如何能够确定属性是string
/ Money
/ int
/ AliasedValue
/等类型?
对于AliasedValue
,CRM使用此类型存储有关返回值的其他信息,并且由于任何属性都可以别名,因此Value
属性可以是任何类型({{1} },OptionSetValue
,decimal
,string
,Guid
等)。 EntityReference
属性也适当地类型为Value
,因此您必须将其转换为获取有关返回值的任何其他信息。
因此无法进行强制转换,但您可以通过在文件顶部添加object
语句并在定义之前定义每个using
的值来缩短代码并使代码更清晰。分配给AliasedValue
。无论如何,我已经包含了每种数据检索的一个例子;你可以判断你的项目哪个更好。
使用演员:
Contact
使用反射:
using Microsoft.Xrm.Sdk;
...
var nick = (AliasedValue)result.Entities[0].Attributes["nick"];
var mail = (AliasedValue)result.Entities[0].Attributes["mail"];
var contact = new Contact
{
Name = nick.Value, //Value is of type object; cast again for a more specific type
Mail = mail.Value
};
使用动态:
var nick = result.Entities[0].Attributes["nick"]
.GetType()
.GetProperty("Value")
.GetValue(result.Entities[0].Attributes["nick"], null);
var mail = result.Entities[0].Attributes["mail"]
.GetType()
.GetProperty("Value")
.GetValue(result.Entities[0].Attributes["mail"], null);
var contact = new Contact
{
Name = nick,
Mail = mail
};
答案 1 :(得分:1)
我想你想要这样的东西:
//Get Account PrimaryContact details
public static void GetAccountPrimaryContactDetails(Guid accountId, IOrganizationService orgService)
{
var contactFirstName = default(object);
var contactLastName = default(object);
var contactFullName = default(object);
string fetchXML = string.Format(@"<fetch version='1.0' output-format='xml-platform' no-lock='true' mapping='logical'>
<entity name='account'>
<attribute name='name' />
<filter type='and'>
<condition attribute='statuscode' operator='eq' value='1' />
<condition attribute='accountid' operator='eq' value='{0}' />
</filter>
<link-entity name='contact' from='contactid' to='primarycontactid' alias='ab'>
<attribute name='fullname' alias='as_fullname' />
<attribute name='firstname' alias='as_firstname' />
<attribute name='lastname' alias='as_lastname' />
</link-entity>
</entity>
</fetch>", accountId.ToString());
var fetchExp = new FetchExpression(fetchXML);
EntityCollection accountEntity = orgService.RetrieveMultiple(fetchExp);
if (accountEntity.Entities.Count > 0)
{
//Primary Contact Fullname
AliasedValue avContactFullname = accountEntity.Entities[0].GetAttributeValue<AliasedValue>("as_fullname");
if (avContactFullname != null)
contactFullName = avContactFullname.Value;
//Primary Contact Firstname
AliasedValue avContactFirstname = accountEntity.Entities[0].GetAttributeValue<AliasedValue>("as_firstname");
if (avContactFirstname != null)
contactFirstName = avContactFirstname.Value;
//Primary Contact Lastname
AliasedValue avContactLastname = accountEntity.Entities[0].GetAttributeValue<AliasedValue>("as_lastname");
if (avContactLastname != null)
contactLastName = avContactLastname.Value;
答案 2 :(得分:0)
我们定义了一个GetValue辅助函数来处理为你检查别名值
public static T GetValue<T>(this Entity entity, string attributeName)
{
if (entity.Attributes.ContainsKey(attributeName))
{
var attr = entity[attributeName];
if (attr is AliasedValue)
{
return GetAliasedValueValue<T>(entity, attributeName);
}
else
{
return entity.GetAttributeValue<T>(attributeName);
}
}
else
{
return default(T);
}
}
这使用内部额外辅助方法来获取别名字段值
private static T GetAliasedValueValue<T>(this Entity entity, string attributeName)
{
var attr = entity.GetAttributeValue<AliasedValue>(attributeName);
if (attr != null)
{
return (T)attr.Value;
}
else
{
return default(T);
}
}
它被定义为Entity类的扩展方法,因此您可以像SDK提供的GetAttributeValue一样使用它 - 您只需记住使用别名字段名称。
var myValue = myEntity.GetValue<string>("alias.fieldname")