当我能够设置值时,为什么我的 Enitty.Contains(attributeField) 返回 false?

Why is my Enitty.Contains(attributeField) returning false when I am able to set the value?

我有一段代码无法正常工作。

我已经按如下方式设置了一个实体,并且有一个以前的 guid。

parentEnt = new Entity("vehicle_ent");
parentEnt.id = guid;

现在,当我使用语句进行检查时:

if (parentEnt.Contains("attribute_field")) {
    parentEnt["attribute_field"] = "test";
}

上面的代码永远不会被调用,因为 if 语句失败了。

但是,如果我删除 if 语句。我能够实际分配 运行 代码:

parentEnt["attribute_field"] = "test";

Contains 方法是否遗漏了什么?我以为它是用来检查实体是否包含属性的?

当您 运行 CRM 实体对象的构造函数,并为其分配一个 guid 喜欢

Entity parentEnt = new Entity("vehicle_ent");
parentEnt.id = guid;

您正在创建实体类型的新对象,逻辑名称为 'vehicle_ent',ID 为 'guid' 此时所有 attribute/properties 属于具有该实体的实体名称,不与实体对象一起创建,并且您只有一个实体 class 对象,其中设置了 LogicalName 和 id。

如果您想检查具有该 ID 的实体记录是否包含某个属性,您需要使用您的组织服务从数据库中获取,例如

ColumnSet attributes = new ColumnSet(true);
parentEnt = _service.Retrieve("vehicle_ent", guid, attributes);

调用检索后,您可以检查实体记录是否包含您需要检查的属性。

在实体 class 上,您始终可以像您提供的示例一样分配一个属性,无论它是否存在。如果它存在,它将覆盖它(这是你发现的)。

所以

parentEnt["attribute_field"] = "test";

将始终有效,无论该属性是否已经分配了值。

我只是补充几点:

语法entity[attributename]entity.Attributes[attributename]是等价的,原因可以在实体元数据里面找到:

public object this[string attributeName] { get; set; } 

该方法在实体级别映射 Attributes 属性(此 属性 的类型是 AttributeCollection 继承自 DataCollection<string,object> 和基本类型是一个 IEnumerable<KeyValuePair<TKey, TValue>>)

DataCollection 包含此方法:

    // Summary:
    //     Gets or sets the value associated with the specified key.
    //
    // Parameters:
    //   key:
    //     Type: TKey. The key of the value to get or set.
    //
    // Returns:
    //     Type: TValue The value associated with the specified key.
    public virtual TValue this[TKey key] { get; set; }

如果键(我们的属性名称)之前不存在,此方法会在集合中添加该键。为此,您可以在不首先使用 Contains 方法的情况下为属性赋值。当然,当您读取值时,您需要检查密钥是否存在,这就是 Contains 方法的目的,但是要读取值,也可以使用 GetAttributeValue (但这是必要的注意当属性不在集合中时返回的默认值)