Motivation
I have a plugin which renews an entity by copying the old on and updating the new entity fields in various ways. My problem is that not all fields are updated the same way. For example, not all dates have their year incremented by 1. Half do, and the last two quarters are copied or cleared. I am using the early-bound entity classes for CRM 2011. I want to leverage those classes to have a compile-time safe way to group the fields of the entities into lists. I can extract the string key for the AttributeCollection given any entity.FieldName. Now I need some construct, syntactic sugaring, thing-in-C#-that-I-haven't-found to be able to chain accessing those fields into the string key name extractor. (hopefully my example Want code clears up any confusion).
Fields of the same type within the same section of the entity form generally have the same kind of update, but that logical ordering is not available in the early-bound class. For example, all of the date fields within a certain collapsible menu all get cleared, but the entity class does not have any knowledge of the form level grouping because it is all XML.
I could loop over the Attributes collection of the old and new entity, comparing the value of each matching key, and display the differences, but I think that requires too much manual validation. It does not make a good automated test.
What I Actually Want To Do
I would like to be able to specify only the fields that were updated without having to type out the string keys for the entity's AttributeCollection dictionary. I was hoping I could borrow or locate a corresponding a syntax from VB (the using
syntax) or something similar to chain calls to the entity's fields via dot notation (see the code example).
HERE IS A SAMPLE OF WHAT I WANT TO DO
Thanks to this question for the GetPropertyName method. It is great! Maybe the lambda will need to be altered slightly to take multiple parameters...
// Gets the string name of whatever object or class property is passed in a lambda
// Usage: GetPropertyName( () => someObject.Property ); ==> "Property"
public string GetPropertyName<T>(Expression<Func<T>> propertyLambda)
// normal use of GetPropertyName is quite helpful
// assume early_bound_entity has fields: name, start_date, end_date, and currency
var e = new early_bound_entity();
string s = GetPropertyName( () => e.start_date); // s => "start_date"
// The "block" I do inside of GetPropertyName is what I am hoping to be able to do!
// i.e. pass as many System.Reflection.MemberInfo instances to GetPropertyName as I can
// I really want to NOT have to say e.field, e.anotherfield, ... but C# does not have VB's using syntax :(
List<string> fieldsShouldHaveCopied = GetPropertyName( (early_bound_entity e) => e.name, e.start_date, e.end_date, e.currency );
// fieldsShouldHaveCopied => { "name", "start_date", "end_date", "currency" }
WHY this way?
I was hoping I could use the class definition of my early-bound entity and set up a context around my early-bound object. Then, using its intellisense and class definition, restrict what fields are grouped together. I really do not want to type out the late-bound Entity.Attributes string keys because that would be horrible to maintain - no intellisense, no compile-time verification, the string could be misspelled, etc. I can check that the AttributeCollection contains the key first and warn that a bad key was used (and will do that anyway), but then future developers would be stuck maintaining "hand-written" Lists of string literals. I would prefer the GetPropertyName method generate those string lists, when I pass in some kind of expression chaining through the early_bound_entity fields which I hope was clear from the code example.
I apologize if I have abused the terms block, closure, and lambda by grouping them together whenever I mention any one of them.
Also, go right ahead and tell me if this is a [stupid|terrible|etc.] idea, and tell me why! I am faced with the prospect of having to type out ~300 field accessors via dot notation (or even their string keys ) just to verify that they were updated. It is quite possible that this entity is too big, but that is sadly the status quo.
Thanks!