CRM 2011, C#: Entity Class redefined with .net framwork 3.5 to connect CRM 2011

Look at my previous post on connecting CRM 2011 using .net framework 3.5 without CRM 2011 SDK. https://consultrikin.wordpress.com/2013/09/19/crm-2011-c-connect-crm-2011-without-using-sdkusing-net-framework-3-5/

Here, if you use Entity Class to create Entity records the same way we create records in .net framework 4.0 with SDK in late bound; this requires following syntax.

Entity entity = new Entity();
entity.LogicalName = "contact";
entity.Attributes = new ServiceReference1.AttributeCollection();
entity.Attributes.Add(new KeyValuePair<string, object>("firstname", "test first name"));
entity.Attributes.Add(new KeyValuePair<string, object>("lastname", "test last name"));
OrgService.Create(entity);

Here, you must add an attribute value as a new KeyValuePair<string, object>. Or you need to access the attributes by their indexes like:

Entity entity = new Entity();
entity.LogicalName = "contact";
entity.Attributes = new ServiceReference1.AttributeCollection();
entity.Attributes[0] = "test first name";
entity.Attributes[1] = "test last name";
OrgService.Create(entity);

This code does not have readability as you need to find int index every time you access entity. While I found the same extended Entity Class from the posts I mentioned in my previous post. Here they are listed. Just add them to your project and you will be able to add attributes with string parameters.

/// <summary>
/// Entity Class
/// </summary>
partial class Entity
{
	/// <summary>
	/// Initializes a new instance of the <see cref="Entity" /> class.
	/// </summary>
	public Entity()
	{
		this.FormattedValuesField = new FormattedValueCollection();
		this.RelatedEntitiesField = new RelatedEntityCollection();
	}

	/// <summary>
	/// Gets the attribute value.
	/// </summary>
	/// <typeparam name="T"></typeparam>
	/// <param name="attributeLogicalName">Name of the attribute logical.</param>
	/// <returns></returns>
	public T GetAttributeValue<T>(string attributeLogicalName)
	{
		if (null == this.Attributes)
		{
			this.Attributes = new AttributeCollection();
		};
		object value;
		if (this.Attributes.TryGetValue(attributeLogicalName, out value))
		{
			return (T)value;
		}

		return default(T);
	}

	/// <summary>
	/// Gets or sets the <see cref="System.Object"/> with the specified attribute name.
	/// </summary>
	/// <value>
	/// The <see cref="System.Object"/>.
	/// </value>
	/// <param name="attributeName">Name of the attribute.</param>
	/// <returns></returns>
	public object this[string attributeName]
	{
		get
		{
			if (null == this.Attributes)
			{
				this.Attributes = new AttributeCollection();
			};

			return this.Attributes.GetItem(attributeName);
		}
		set
		{
			if (null == this.Attributes)
			{
				this.Attributes = new AttributeCollection();
			};

			this.Attributes.SetItem(attributeName, value);
		}
	}
}

And Add following Class-

/// <summary>
/// CollectionExtensions Class
/// </summary>
public static class CollectionExtensions
{
	/// <summary>
	/// Gets the item.
	/// </summary>
	/// <typeparam name="TKey">The type of the key.</typeparam>
	/// <typeparam name="TValue">The type of the value.</typeparam>
	/// <param name="collection">The collection.</param>
	/// <param name="key">The key.</param>
	/// <returns>returns TValue</returns>
	/// <exception cref="System.Collections.Generic.KeyNotFoundException">Key =  + key</exception>
	public static TValue GetItem<TKey, TValue>(this IList<KeyValuePair<TKey, TValue>> collection, TKey key)
	{
		TValue value;
		if (TryGetValue(collection, key, out value))
		{
			return value;
		}

		throw new System.Collections.Generic.KeyNotFoundException("Key = " + key);
	}

	/// <summary>
	/// Sets the item.
	/// </summary>
	/// <typeparam name="TKey">The type of the key.</typeparam>
	/// <typeparam name="TValue">The type of the value.</typeparam>
	/// <param name="collection">The collection.</param>
	/// <param name="key">The key.</param>
	/// <param name="value">The value.</param>
	public static void SetItem<TKey, TValue>(this IList<KeyValuePair<TKey, TValue>> collection, TKey key, TValue value)
	{
		int index;

		if (TryGetIndex<TKey, TValue>(collection, key, out index))
		{
			collection.RemoveAt(index);
		}

		//If the value is an array, it needs to be converted into a List. This is due to how Silverlight serializes
		//Arrays and IList<T> objects (they are both serialized with the same namespace). Any collection objects will
		//already add the KnownType for IList<T>, which means that any parameters that are arrays cannot be added
		//as a KnownType (or it will throw an exception).
		Array array = value as Array;
		if (null != array)
		{
			Type listType = typeof(List<>).GetGenericTypeDefinition().MakeGenericType(array.GetType().GetElementType());
			object list = Activator.CreateInstance(listType, array);
			try
			{
				value = (TValue)list;
			}
			catch (InvalidCastException)
			{
				//Don't do the conversion because the types are not compatible
			}
		}

		collection.Add(new KeyValuePair<TKey, TValue>(key, value));
	}

	/// <summary>
	/// Determines whether the specified collection contains key.
	/// </summary>
	/// <typeparam name="TKey">The type of the key.</typeparam>
	/// <typeparam name="TValue">The type of the value.</typeparam>
	/// <param name="collection">The collection.</param>
	/// <param name="key">The key.</param>
	/// <returns>returns true or false</returns>
	public static bool ContainsKey<TKey, TValue>(this IList<KeyValuePair<TKey, TValue>> collection, TKey key)
	{
		int index;
		return TryGetIndex<TKey, TValue>(collection, key, out index);
	}

	/// <summary>
	/// Tries the get value.
	/// </summary>
	/// <typeparam name="TKey">The type of the key.</typeparam>
	/// <typeparam name="TValue">The type of the value.</typeparam>
	/// <param name="collection">The collection.</param>
	/// <param name="key">The key.</param>
	/// <param name="value">The value.</param>
	/// <returns>returns true or false</returns>
	public static bool TryGetValue<TKey, TValue>(this IList<KeyValuePair<TKey, TValue>> collection, TKey key, out TValue value)
	{
		int index;
		if (TryGetIndex<TKey, TValue>(collection, key, out index))
		{
			value = collection[index].Value;
			return true;
		}

		value = default(TValue);
		return false;
	}

	/// <summary>
	/// Tries the index of the get.
	/// </summary>
	/// <typeparam name="TKey">The type of the key.</typeparam>
	/// <typeparam name="TValue">The type of the value.</typeparam>
	/// <param name="collection">The collection.</param>
	/// <param name="key">The key.</param>
	/// <param name="index">The index.</param>
	/// <returns>returns true or false</returns>
	private static bool TryGetIndex<TKey, TValue>(IList<KeyValuePair<TKey, TValue>> collection, TKey key, out int index)
	{
		if (null == collection || null == key)
		{
			index = -1;
			return false;
		}

		index = -1;
		for (int i = 0; i < collection.Count; i++)
		{
			if (key.Equals(collection[i].Key))
			{
				index = i;
				return true;
			}
		}

		return false;
	}
}

Happy Programming!!

11 thoughts on “CRM 2011, C#: Entity Class redefined with .net framwork 3.5 to connect CRM 2011

  1. Pingback: CRM 2011, C#: Connect CRM 2011 without using SDK/using .Net Framework 3.5 | Consult Rikin

  2. For Native fields this works correctly but when i tried to create an entity record with Option set values, the response says that i have a namespaces problem.

    How can i solve this problem?

  3. Hi,
    In your reference.cs , search “class Entity”, “class EntityReference”
    Above these two partial classes, add these two lines

    [System.Runtime.Serialization.KnownTypeAttribute(typeof(OptionSetValue))]
    [System.Runtime.Serialization.KnownTypeAttribute(typeof(EntityReference))]

    Now search for “class OrganizationRequest”.
    Add these lines above it:

    [System.Runtime.Serialization.KnownTypeAttribute(typeof(EntityReference))]
    [System.Runtime.Serialization.KnownTypeAttribute(typeof(PrincipalAccess))]
    [System.Runtime.Serialization.KnownTypeAttribute(typeof(OptionSetValue))]

    Now, go to your actual code and for lookup field use like this:

    myAttColl.Add(new KeyValuePair(“parentcustomerid”, new EntityReference() {Id = t.Id, LogicalName= t.LogicalName}));

    Build the solution and it should work now.

  4. Excellent @Rikin it worked perfectly, the only thing to get in mind is that the update of the web reference can undo all the changes over the reference.cs file, Tanks a lot

  5. Pingback: CRM 2011, C#, v3.5: Type ‘OptionSetValue’ with data contract name ‘OptionSetValue:http://schemas.microsoft.com/xrm/2011/Contracts’ is not expected | Consult Rikin

  6. Hi Expert ,
    Awesome post , but i got stuck with Activity party field ,
    I am currently trying to create Email record i could not able to set value for “From ” & “To” field .
    Kindly provide me some sample on how to set value for “Activityparty”. (late bound)

  7. Hi Expert ,
    Awesome post , but i got stuck with Activity party field ,
    I am currently trying to create Email record i could not able to set value for “From ” & “To” field .
    Kindly provide me some sample on how to set value for “Activityparty”. (late bound)

    • Hi,

      They are available everywhere…

      Entity from1 = new Entity(“activityparty”);
      Entity to1 = new Entity(“activityparty”);
      Entity to2 = new Entity(“activityparty”); // two contacts inside the to field

      from1[“partyid”]= new EntityReference(“systemuser”, userId);
      to1[“partyid”]= new EntityReference(“contact”, contact1Id);
      to2[“partyid”]= new EntityReference(“contact”, contact2Id);

      Regards,
      Rikin

      • Hi adding to your point ,
        once i added KnownType of EntityCollection , it get worked.

        [System.Runtime.Serialization.KnownTypeAttribute(typeof(EntityCollection))]
        [System.Runtime.Serialization.KnownTypeAttribute(typeof(OptionSetValue))]
        [System.Runtime.Serialization.KnownTypeAttribute(typeof(EntityReference))]

        public partial class Entity { }

        Thanks ,

Leave a comment