6

我正在获取营销列表列表。当我这样做时,根据我使用智能感知的检查,这似乎是一个成功的操作。当我寻找时,...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'ing it to 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
}

我的意思是,说真的 - 这是一段丑陋的代码......必须有更好的方法!但是,我担心不是因为这个讨论似乎也在使用那种语法......

4

3 回答 3

7

查看文档,对象的Attributes属性Entity是类型AttributeCollection,它派生自DataCollection<string,Object>.

对于集合中的每个属性,都有一个键/值对。

因此,对于每个键(“nick”、“mail”),都有一个对应object的 .NET 类型。您必须将对象转换为正确的类型(就像您所做的那样)才能访问您正在寻找的属性(或者使用反射,这肯定会更丑陋,或者我认为在 C# 4.0 中dynamictype,但在那情况下,您将失去编译时检查);编译器如何才能确定属性是否属于string/ Money/ int/ AliasedValue/等类型?

至于AliasedValue,CRM 使用这种类型来存储有关返回值的附加信息,并且由于任何属性都可以别名,因此Value属性可以是任何类型(OptionSetValuedecimalstringGuidEntityReference等)。然后该Value属性也适当地属于 type 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
};

使用动态:

dynamic nick = result.Entities[0].Attributes["nick"];
dynamic mail = result.Entities[0].Attributes["mail"];

var contact = new Contact
{
    Name = nick.Value, //dynamic figures out the right property at runtime
    Mail = mail.Value
};
于 2012-09-28T22:21:28.820 回答
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;
于 2018-04-18T14:25:00.157 回答
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")
于 2018-04-20T15:54:51.443 回答