Friday, October 23, 2009

Best practice to develop jQuery plugin

  1. Create a private scope for $
  2. Attach plugin to $.fn alias
  3. Add implicit iteration
  4. Enable chaining
  5. Add default options
  6. Add custom options
  7. global custom options
<!DOCTYPE html><html lang="en"><body> <div id="counter1"></div><div id="counter2"></div> <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.3.2/jquery.min.js"></script><script> (function($) { $.fn.count = function(customOptions){ var options = $.extend({},$.fn.count.defaultOptions, customOptions); return this.each(function(){ var $this = $(this); $this.text(options.startCount); var myInterval = window.setInterval(function(){ var currentCount = parseFloat($this.text()); var newCount = currentCount+1; $this.text(newCount+''); }, 1000); }); }; $.fn.count.defaultOptions = { startCount:'100' }; })(jQuery); jQuery.fn.count.defaultOptions.startCount = '300'; jQuery('#counter1').count(); jQuery('#counter2').count({startCount:'500'}); </script></body></html>

Wednesday, October 21, 2009

type check in jQuery

String: typeof object === "string" Number: typeof object === "number" Boolean: typeof object === "boolean" Object: typeof object === "object" Function: jQuery.isFunction(object) Array: jQuery.isArray(object) Element: object.nodeType null: object === null undefined: typeof variable === "undefined" or object.prop === undefined null or undefined: object == null

Saturday, October 17, 2009

it must be "new"ed.

The following is constructor which prevent not using "new" keyword

function User(first, last){ if ( !(this instanceof arguments.callee) ) return new User(first, last); this.name = first + " " + last; }

Friday, October 16, 2009

javascript scope

In JavaScript, {blocks} do not have scope. Only functions have scope. Vars defined in a function are not visible outside of the function.

function overload

function.length can tell you the number of parameters defined, using this we can create overload functions

function addMethod(object, name, fn){ // Save a reference to the old method var old = object[ name ]; // Overwrite the method with our new one object[ name ] = function(){ // Check the number of incoming arguments, // compared to our overloaded function if ( fn.length == arguments.length ) // If there was a match, run the function return fn.apply( this, arguments ); // Otherwise, fallback to the old method else if ( typeof old === "function" ) return old.apply( this, arguments ); }; } function Ninjas(){ var ninjas = [ "Dean Edwards", "Sam Stephenson", "Alex Russell" ]; addMethod(this, "find", function(){ return ninjas; }); addMethod(this, "find", function(name){ var ret = []; for ( var i = 0; i < ninjas.length; i++ ) if ( ninjas[i].indexOf(name) == 0 ) ret.push( ninjas[i] ); return ret; }); addMethod(this, "find", function(first, last){ var ret = []; for ( var i = 0; i < ninjas.length; i++ ) if ( ninjas[i] == (first + " " + last) ) ret.push( ninjas[i] ); return ret; }); } var ninjas = new Ninjas(); assert( ninjas.find().length == 3, "Finds all ninjas" ); assert( ninjas.find("Sam").length == 1, "Finds ninjas by first name" ); assert( ninjas.find("Dean", "Edwards").length == 1, "Finds ninjas by first and last name" ); assert( ninjas.find("Alex", "X", "Russell") == null, "Does nothing" );

later method

Object.prototype.later = function (msec, method) {     var that = this, args = Array.prototype.slice. apply(arguments, [2]); if (typeof method === 'string') { method = that[method]; } setTimeout(function () { method.apply(that, args); }, msec); return that; };

fixed a closure bug

Closure refer the ability that a function can access and manipulate external variable from with a function. Sometimes, this is not good because the if a function depends on the external state, and the external state changes, when the function may produce unexpected result.

//this is because the function inside setTimeout refers to the i only when it is //executed, by then i==4, the problem is that i is external variable for (var i = 0; i < 4; i++) { setTimeout(function() { alert(i); //it is always 4 }, i * 1000); } //the solution is make the i as local variable, so parameter is a solution, and //self-execution var count = 0; for (var i = 0; i < 4; i++) { (function(j) { setTimeout(function() { alert(j); //it will show 0, 1, 2, 3 }, j * 1000); }) (i); }

So sometimes it is good to remove the external dependencies. The follow code is anther example.

var ninja = { yell: function(n) { return n > 0 ? arguments.callee(n - 1) + "a" : "hiy"; } } /* this is also ok var ninja = { yell: function x(n) { return n > 0 ? x(n - 1) + "a" : "hiy"; } }; */ /*this is has bug, because ninja.yell is inside of function which depends external state var ninja = { yell: function(n) { return n > 0 ? ninja.yell(n - 1) + "a" : "hiy"; } }; */ var sumurai = { yell: ninja.yell }; ninja = null; ok(sumurai.yell(4) == "hiyaaaa", "argumnets.collee is the function itself");

efficency string operation

Because string is immutable in JavaScript, concatenation with array.join('') is much efficient. The following code use all the chinese characters. Click here to show

var sb = []; sb[sb.length] = "<p>"; for (var i = 0x4e00; i <= 0x9fcf; i++) { sb[sb.length] = String.fromCharCode(i); } sb[sb.length] = "</p>"; $("#chinese").html(sb.join("")); return false;

the bind function

John Resig has page Learning Advanced JavaScript to explain how the following script works.

// The .bind method from Prototype.js Function.prototype.bind = function(){ var fn = this, args = Array.prototype.slice.call(arguments), object = args.shift(); return function(){ return fn.apply(object, args.concat(Array.prototype.slice.call(arguments))); }; };

His explanation is wonderful. And this piece of code is simple, powerful. But it maybe still hard for anyone to understand without any explanation. So I refactored it as follow, and add one use case.

Function.prototype.bind = function() { var function_to_be_bound = this; var args = Array.prototype.slice.call(arguments); var context_object = args.shift(); var binding_parameters = args; return function() { var invoking_parameters = Array.prototype.slice.call(arguments); var combined_parameters = binding_parameters.concat(invoking_parameters); var result_from_function_run_in_new_context = function_to_be_bound.apply(context_object, combined_parameters); return result_from_function_run_in_new_context; }; } function reply_greeting(your_name) { //"this" is the context object alert("my name is " + this.name + ", Nice to meet you, " + your_name); } var fred = { name: "fred" }; var reply_greeting_of_fred_to_you = reply_greeting.bind(fred); var reply_greeting_of_fred_to_john = reply_greeting.bind(fred, "john"); reply_greeting_of_fred_to_you("jeff"); //expect: "my name is fred, Nice to meet you, jeff" reply_greeting_of_fred_to_john(); //expect: "my name is fred, Nice to meet you, john"

Another article may help you to understand is Functional Javascript

Thursday, October 15, 2009

memoried function

Function.prototype.memorized = function(key) { this._values = this._values || {}; if (this._values[key] !== undefined) { return this._values[key] } else { //"this" is parent function object this._values[key] = this.apply(this, arguments); /* the "this" passed as context object is optional? */ return this._values[key]; } }; function isPrime(num) { alert(this); var prime = num != 1; for (var i = 2; i < num; i++) { if (num % i == 0) { prime = false; break; } } return prime; } var a = isPrime.memorized(5); alert(a); var b = isPrime.memorized(5); alert(b);

curry function

Function.method('curry', function() { //arguments can not be passed in to closure function //var l = arguments.length; //var args = []; //for (var i = 0; i < l; i++) { // args[i] = arguments[i]; //} var args = Array.prototype.slice.apply(arguments); var original_function = this; return function() { //arguments is not the external arguments //for (var i = 0; i < arguments.length; i++) { // args[args.length] = arguments[i]; //} args = args.concat(Array.prototype.slice.call(arguments)); return original_function.apply(null, args); }; }); function add() { var sum = 0; for (i = 0; i < arguments.length; i++) { sum += arguments[i]; } return sum; } var add1 = add.curry(1); var s = add1(2); alert(s);

Tuesday, October 13, 2009

an issue caused by prototype inheritance in javascript

This issue is not obvious, in some case, it does not even cause any error at all. But fixing this issue brings some benefit. Here the use case.

var user_constructor = function() { alert(this.constructor); //function() { alert(this .. }; this.constructor.count++; this.Id = this.constructor.count; }; user_constructor.count = 0; var c = new user_constructor(); alert(c.Id); //1 alert(c.constructor == user_constructor); //true alert(user_constructor.count); //1

We know that constructor is also an object, (an object is not necessarily a constructor), in our case our constructor has property "count" to count the instance created by the constructor. And the Id is this last count. Very straight forward. Now if we want add in inheritance, we can implement as follow.

var user_constructor = function() { alert(this.constructor); //function Object() { [native code] } this.constructor.count++; this.Id = this.constructor.count; }; user_constructor.count = 0; var user_prototype = { Name: "Unknown" }; user_constructor.prototype = user_prototype; var c = new user_constructor(); alert(c.Id); //NaN alert(c.constructor == user_constructor); //false alert(user_constructor.count); //0

Suddenly, the code broke down. Is it because the fault of the prototype object? No. We need to have deeper understand how constructor works. When an object is created by using "new user_constructor()", the javascript runtime need to determine what constructor is used used to create an object "this". But how. According to ECMAScript Language Specification Edition 3

ECMAScript supports prototype-based inheritance. Every constructor has an associated prototype,and every object created by that constructor has an implicit reference to the prototype(calledthe object’s prototype)associated with its constructor.

To implement this feature, the runtime need to create "this" that has be behavior of user_constructor.prototype, so runtime will use user_constructor.prototype.constructor function to create "this". In the first case, there is no prototype based inheritance. So user_constructor.prototype is [object Object], naturally, user_constructor.prototype.constructor should [object Object] as well, but it is actually function() { alert(this .. }. Why. I don't know exactly, but this may be because user_constructor has no user assigned prototype, so the object should be created by user_constructor itself. In the second case, user_constructor.prototype is user_prototype, which is create by "function Object() { [native code] }". So runtime will use that function as constructor. After we rationalize this, we can easily fix this behavior as follow by adding one line "user_prototype.constructor = user_constructor;"

var user_constructor = function() { alert(this.constructor); //function() { alert(this .. }; this.constructor.count++; this.Id = this.constructor.count; }; user_constructor.count = 0; var user_prototype = { Name: "Unknown" }; user_constructor.prototype = user_prototype; user_prototype.constructor = user_constructor; var c = new user_constructor(); alert(c.Id); //NaN alert(c.constructor == user_constructor); //false alert(user_constructor.count); //0

Sunday, September 27, 2009

4 Equals, Reference Type, Value Type

The very fundamental design in .net clr is that type system is classified into two type, reference type and value type. This design decision has profound implication on the .net. One examples is to test the equality between objects.

Basically we have two kinds of comparison, identity comparison(whether two object has the same identity), semantic comparison(whether two object means the same thing, most people use value equality comparison, I use "semantic" because value of reference type is a reference, event the values of reference typed variable are the sames, it is possible that they mean the same thing in semantics). Since we have the two different type, this makes things complicated. For example, can we compare the "value" of reference type, or can we compare the reference of value type. If there had been only reference type, if there had been no value type, the .net world will be simpler. Why we need two types? This is a deep question, lots of this topics has been covered in a book "CLR via C#". Basically, this a consideration of memory efficiency and performance. What we need to know is that the value of reference type is reference, the value of value type is value.

Reference type identity comparison

To do identity comparison for reference type, we should call Object.ReferenceEquals(objA, objB), or you can use shortcurt operator "==" like "objA == objB". The following source code shows that ReferenceEquals and == operator is the same.

public class Object { [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)] public static bool ReferenceEquals (Object objA, Object objB) { return objA == objB; } }

If they are the same, why we still need ReferenceEquals. It turns "==" means different things for different type value type. What exactly "==" does? For all reference type and all primitive value type, like int, double, enum, it become "ceq" instruction after it is compiled msil. What does "ceq" do? It is clr implementation question, I guess it compare identity equal for reference type and compare value equal for primitive value type. But it means "==" operator for custom value type like struct, which has not default implementation.

Reference type semantic comparison

The default semantic comparison of reference type is identity comparison, because the value of reference type variable is a reference. The default implementation is as follow.

// Returns a boolean indicating if the passed in object obj is // Equal to this. Equality is defined as object equality for reference // types and bitwise equality for value types using a loader trick to // replace Equals with EqualsValue for value types). // public virtual bool Equals(Object obj) { return InternalEquals(this, obj); } [MethodImplAttribute(MethodImplOptions.InternalCall)] internal static extern bool InternalEquals(Object objA, Object objB);

According the comments, for reference type object, InternalEquals just compare the reference, it does not compare referenced content. The following code shows this behavior.

static void Main(string[] args) { Customer c1 = new Customer { Name = "fred" }; Customer c2 = new Customer { Name = "fred" }; Customer c3 = c1; Console.WriteLine(object.ReferenceEquals(c1, c2)); //False Console.WriteLine(object.ReferenceEquals(c1, c3)); //True Console.WriteLine(c1 == c2); //False Console.WriteLine(c1 == c3); //True Console.WriteLine(c1.Equals(c2)); //False, event the reference content is same Console.WriteLine(c1.Equals(c3)); //True } public class Customer { public string Name { get; set; } }

But sometimes, we want to change this semantics. In our case, we can say if the name of customer is the same, regardless their identity. So we can override the instance Equals method like the following.

public class Customer { public string Name { get; set; } public override bool Equals(object obj) { var c = obj as Customer; if (c == null) { return false; } else { return this.Name == c.Name; } } }

Value type identity comparison

Can you compare identity of value type variable. "Yes". Should you compare identity of value types variable. "No". The result will always return "False", because object put in different boxes before comparison.

Console.WriteLine(object.ReferenceEquals(1, 1)); // False

Value type semantic comparison

Although you can use "==" operator with primitive value type like System.Int32, but you can not use it with custom value type such as struct before you implement the operator by your self. But you can use object type's instance Equals to do semantic comparison, which use reflection to check content equality like below.

public abstract class ValueType { public override bool Equals (Object obj) { BCLDebug.Perf(false, "ValueType::Equals is not fast. "+this.GetType().FullName+" should override Equals(Object)"); if (null==obj) { return false; } RuntimeType thisType = (RuntimeType)this.GetType(); RuntimeType thatType = (RuntimeType)obj.GetType(); if (thatType!=thisType) { return false; } Object thisObj = (Object)this; Object thisResult, thatResult; // if there are no GC references in this object we can avoid reflection // and do a fast memcmp if (CanCompareBits(this)) return FastEqualsCheck(thisObj, obj); FieldInfo[] thisFields = thisType.GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); for (int i=0; i<thisFields.Length; i++) { thisResult = ((RtFieldInfo)thisFields[i]).InternalGetValue(thisObj,false); thatResult = ((RtFieldInfo)thisFields[i]).InternalGetValue(obj, false); if (thisResult == null) { if (thatResult != null) return false; } else if (!thisResult.Equals(thatResult)) { return false; } } return true; } }

So we should always override instance Equals() for your custom value type struct to improve performance.

Comparing objects of unknown type

If we don't know the types of two object, the best bet is to use static method object.Equals(objA, objB). This method check if the identity equal first, then check semantic equality, this if This method is as follow.

public static bool Equals(Object objA, Object objB) { if (objA==objB) { return true; } if (objA==null || objB==null) { return false; } return objA.Equals(objB); }

To wrap it, what does this means to me? We can follow the following pseudo code

if (we compare two object of the same type) { if (type is reference type) { if (we want semantic compare && we have override the objA.Eqauls method) { objA.Equals(B); } else //we just want to identity compare { always use "objA == objB"; but object.ReferneceEqual(objA, objB) and objA.Eqauls(objB) do the same thing in this case } } else //type is value type { if (we want identity compare) { forget about it, although we can call object.ReferenceEqual(objA, objB) it will always return false because of boxing } else //we should always use semantic compare { if (type is primitive value type like int) { x == y // it is compiled to ceq il instruction } else { if (you have implment the == operator for this type) { use objA == objB } else { use objA.Equels(objB) //if you want more efficent comparison override instece Equals method } } } } } else //we compare two object of unknown type { Object.Equals(objA, objB); }

For reference type, "==" is enough for a situation, unless you want to change the default semantics comparison. For primitive value type, "==" is enough for most situations. For struct, you are encourage to override default semantics comparison obj.Equals() for performance, although not mandatory, and use obj.Equals for comparison.

Saturday, September 26, 2009

IEnumberable, IQueryable , Lambda expression - part2

I have seen such following piece of code written by a developer from a client.

interface IContactRepository { IEnumberable<Contact> GetSomeContacts(); } class ContactRepository : IContactRepository { public IEnumerable<Contact> GetSomeContacts() { //query is linq to sql query object IQueryable<Contact> query = ... return query; } }

Is it a better choice to using IEnumerable<T> instead of IQueryable<T>. I guess his concerns is that, if the interface is too specific, first this may give client more functionality than is required, second this may limit the server's choice of implementation. In lots case, this concern is right, we should give client the only functionality which client needs, nothing less and nothing more, and server should has more freedom to implement.

interface IPerson { void Eat(); void Sleep(); } interface ISales : IPerson { void Sell(); } interface ITeacher : IPerson { void Teache(); } class Service { //Unappropriate // public ISales GetPerson() // { // return ... // } //better public IPerson GetPerson() { return ... } }

Firstly, if the method return a ISales, First client will have one extra unnecessary method Sell. Secondly If the client only needs a IPerson, and the contract says client needs a IWorker, this will limit server's ability to serve the client, for example, server can not return a ITeacher.

Is this design guideline also applicable to the case of IContactRepository.

public interface IQueryable<T> : IEnumerable<T>, IQueryable, IEnumerable {} public interface IQueryable : IEnumerable { Type ElementType { get; } Expression Expression { get; } IQueryProvider Provider { get; } }

First the the IQuerable<T> interface does give user more functionality than the IEnunumerable<T>, but these members are read only, and client can not use them directly for query. Because the query functionality comes from the static method in Enumerable and Queryable, but not the IQuerable<T>, and IEnumeralbe<T>, from the client's perspective, Two interfaces works identically. Secondly, the interface does limit limit server's implementation choice, because server cannot return a IEnumberable<T> . Initially, I thought I can implement easily a empty IQueryable<T> that wrap a IEnumberable<T>. It turns out to be even easier. Because the Enumerable already implement an static method AsQueryable() for you, the Linq team in Microsoft already expect this is a common use case. So all you need to do is call the method can you IEnumberable&lgt;T> will become IQueryable<T>. like the following.

int[] intEnumerable = { 1, 2, 3 , 5}; IQueryable intQuery = intEnumerable.AsQueryable().Where( number => number > 2); foreach (var item in intQuery) { Console.WriteLine(item); } Console.WriteLine(intQuery.GetType().ToString()); //System.Linq.EnumerableQuery`1[System.Int32] //code decompiled by reflector ParameterExpression CS$0$0000; IQueryable intQuery = new int[] { 1, 2, 3, 5 }.AsQueryable<int>().Where<int>(Expression.Lambda<Func<int, bool>>(Expression.GreaterThan(CS$0$0000 = Expression.Parameter(typeof(int), "number"), Expression.Constant(2, typeof(int))), new ParameterExpression[] { CS$0$0000 })); foreach (object item in intQuery) { Console.WriteLine(item); } Console.WriteLine(intQuery.GetType().ToString());

So a it seems be a better to replace IEnumberable<T> with IQueryable<T>. As for as the interface concerns, the replacement does not give client any exactly same query experience and it is more difficult to implement. A great benefit of this replacement is the performance, using IEnumberable<T> will be much slower than IQuerable<T>. Consider the following code, the Where method for IQueryable<T> will treat the lambda expression as expression tree and query will be executed at server side which is much faster, while the IEnumerable<T> will treat the lambda expression as delegate and query will be executed at client side, which will be slower. Consider the following code.

var thisContact = contaceRepository. GetSomeContacts().Where( ctc => ctc.Id = 1).First();

Linq provide us a new way to design our domain model. In the post Extending the World, author says

Typically for a given problem, a programmer is accustomed to building up a solution until it finally meets the requirements. Now, it is possible to extend the world to meet the solution instead of solely just building up until we get to it. That library doesn't provide what you need, just extend the library to meet your needs.

It is very important to build extensible domain model by taking the advantage of IQueryable<T> interface. Using IEnumberable<T> only will hit the performance very seriously. The only pitfall to user IQueryable<T> is that user may send unnecessary complex to the server, but this can be resolved by designing the method so that only appropriate IQueryable<T> is returned, for example return GetSome instead of GetAll. Another solution is adding a view model which return a IEnumberable<T>

IEnumberable, IQueryable , Lambda expression - part1

When we type the following code

IEnumerable<int> intEnumerable = null; var q1 = intEnumerable.Where( x => x > 10);

we know that Where method is not part of the IEnumberable<T> interface or IEnumberable interface, it comes from extension method of Enumerable, which is static class and it has no inheritance relation With IEnumerable or IEnumberable<T>. The power of Linq-To-Object does not come from IEnumberable or IEnumberable or its implemenation, it comes from the extension method. Let's take a look what does the extension method do? Using Reflector we get the following source code.

public static class Enumerable { public static IEnumerable<TSource> Where<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate) { if (source == null) { throw Error.ArgumentNull("source"); } if (predicate == null) { throw Error.ArgumentNull("predicate"); } if (source is Iterator<TSource>) { return ((Iterator<TSource>) source).Where(predicate); } if (source is TSource[]) { return new WhereArrayIterator<TSource>((TSource[]) source, predicate); } if (source is List<TSource>) { return new WhereListIterator<TSource>((List<TSource>) source, predicate); } return new WhereEnumerableIterator<TSource>(source, predicate); } }

We can see there , the delegate passed in to the method is the code that does the filtering.

IQueryable inherit from IEnumerable. But what extra value does the IQueryable bring. Let's take a look of the following code. and the code it generated by c# compiler.

public interface IQueryable<T> : IEnumerable<T>, IQueryable, IEnumerable {} public interface IQueryable : IEnumerable { Type ElementType { get; } Expression Expression { get; } IQueryProvider Provider { get; } }

It does not tell too much? Let's move on an querable example and decomplie to see what it does.

IQueryable<int> intQuerable = null; var q2 = intQuerable.Where(x => x > 10); // decomplied by reflector ParameterExpression CS$0$0000; IQueryable<int> q2 = intQuerable.Where<int>(Expression.Lambda<Func<int, bool>>(Expression.GreaterThan(CS$0$0000 = Expression.Parameter(typeof(int), "x"), Expression.Constant(10, typeof(int))), new ParameterExpression[] { CS$0$0000 }));

From this example, we can see that the Lamda Expression is not converted to a delegate, but to an expression tree. But why the extension method Enumerable.Where(IEnumerable<TSource> Where<TSource>(this IEnumerable<TSource> source, Func<TSource, bool> predicate) is not used? It turns out that, the c# compiler pick a more a suitable extension from Queryable. Here is the code from Reflector.

public static IQueryable<TSource> Where<TSource>(this IQueryable<TSource> source, Expression<Func<TSource, bool>> predicate) { if (source == null) { throw Error.ArgumentNull("source"); } if (predicate == null) { throw Error.ArgumentNull("predicate"); } return source.Provider.CreateQuery<TSource>(Expression.Call(null, ((MethodInfo) MethodBase.GetCurrentMethod()).MakeGenericMethod(new Type[] { typeof(TSource) }), new Expression[] { source.Expression, Expression.Quote(predicate) })); }

Unlike the Enumerable.Where methhod, this method does not have a delegate to do the filtering. And also the expression can not do the filtering either, it is the IQuerable.Provider which does the filtering. The provider takes the expression tree and does filtering later by converting expression tree to provider specific algorithm like TSQL.

IEumberable<T> is very easy to implement, in fact all the collection they are IEnumberable<T*gt;. Iterator makes it even easier. So there is not such thing as implementing a IEnumberableProvider, because the delegate does the query. But to implement IQueryable is more difficult, because expression does not query. It is IQueryProvider does the job. You need to implement IQuerableProvider

public interface IQueryProvider { IQueryable CreateQuery(Expression expression); IQueryable<TElement> CreateQuery<TElement>(Expression expression); object Execute(Expression expression); TResult Execute<TResult>(Expression expression); }

Sunday, July 19, 2009

Disconnected Update with Entity Framework

In the first demo, we get disconnected entity, make change of it, and get copy of original copy from the database, and apply the changed entity to the original entity by using context.ApplyPropertyChanges method, and save it back to the database.

public void DemoDisconnectedUpdate1() { //using NoTracking to simulate the disconnected enviorment //or you can use context.Detach() to simulate that context.Contacts.MergeOption = MergeOption.NoTracking; var pendingContact = context.Contacts.Where(c => c.ContactID == 709).First(); //change pendingContact.FirstName = "somebody"; // ApplyChange1(pendingContact); } public void ApplyChange1(EntityObject pendingEntity) { context = new PEF(); context.GetObjectByKey(pendingEntity.EntityKey); context.ApplyPropertyChanges(pendingEntity.EntityKey.EntitySetName, pendingEntity); context.SaveChanges(); }

Unlike the first demo, in the second demo, we use a anonymous typed object to represent the change of the entity, and apply the change directly to the original version directly using reflection.

public void DemoDisconnectUpdate2() { EntityKey key = new EntityKey("PEF.Contacts", "ContactID", 709); var changes = new { FirstName = "xyz" }; UpdateEntity(key, changes); } public void UpdateEntity(EntityKey key, object changes) { var original = context.GetObjectByKey(key); ApplyChange(changes, original); context.SaveChanges(); } public void ApplyChange(object changes, object original) { Type newType = changes.GetType(); Type oldType = original.GetType(); var newProperties = newType.GetProperties(); foreach (var newProperty in newProperties) { var oldProperty = oldType.GetProperty(newProperty.Name); if (oldProperty != null) { oldProperty.SetValue(original, newProperty.GetValue(changes, null), null); } } }

Thursday, July 16, 2009

Reference and EntityKey

When add an entity to your objectContext, if the entity reference an other existing entity, but that entity is not in memory, you need to create a EntityKey like the following.

var address = new Address(); address.City = "SomeCity"; address.AddressType = "Home"; address.ModifiedDate = DateTime.Now; address.ContactReference.EntityKey = new EntityKey("PEF.Contacts", "ContactID", 709); context.AddToAddresses(address); context.SaveChanges();

Sunday, July 12, 2009

Naming in Entity Framework

When using the entity framework designer, you create you entity model with a naming convention. For example, a table "Customer" will map to a entity type "Customer" and entity set "CustomerSet" . It is very tempting to change the name of "CustomerSet" to to Customers. But what about Criterion, its plural forms is Criteria, what about Equipment, it is plural forms is also Equipment. I feel that the default naming convention is good enough, because it tells you it is a set and also my configuration is kept to minimum, isn't this the spirit of convention over configuraiton?

How ObjectContext manage entities

Those objects were created by an internal process called object materialization, which takes the returned data and builds the relevant objects for you. Depending on the query, these could be EntityObjects, anonymous types, or DbDataRecords. By default, for any EntityObjects that are materialized, the ObjectContext creates an extra object behind the scenes, called an ObjectStateEntry. It will use these ObjectStateEntry objects to keep track of any changes to their related entities. If you execute an additional query using the same context, more ObjectStateEntry objects will be created for any newly returned entities and the context will manage all of these as well. The context will keep track of its entries as long as it remains in memory. The ObjectContext can track only entities. It cannot keep track of anonymous types or nonentity data that is returned in a DbDataRecord.

ObjectStateEntry takes a snapshot of an entity's values as it is first created, and then stores the original values and the current values as two separate sets. ObjectStateEntry also has an EntityState property whose value reflects the state of the entity (Unchanged, Modified, Added, Deleted). As the user modifies the objects, the ObjectContext updates the current values of the related ObjectStateEntry as well as its EntityState.

The object itself also has an EntityState property. As long as the object is being managed by the context, its EntityState will always match the EntityState of the ObjectStateEntry. If the object is not being managed by the context, its state is Detached.

ObjectContext has a single method, SaveChanges, which persists back to the database all of the changes made to the entities. A call to SaveChanges will check for any ObjectStateEntry objects being managed by that context whose EntityState is not Unchanged, and then will use its details to build separate Insert, Update, and Delete commands to send to the database. ObjectContext can monitor the change of both entity and entity reference.

Pros and Cons of Load and Include

You have some things to consider when choosing between the Load and Include methods. Although the Load method may require additional round trips to the server, the Include method may result in a large amount of data being streamed back to the client application and then processed as the data is materialized into objects. This would be especially problematic if you are doing all of this work to retrieve related data that may never even be used. As is true with many choices in programming, this is a balancing act that you need to work out based on your particular scenario. The documentation also warns that using query paths with Include could result in very complex queries at the data store because of the possible need to use numerous joins. The more complex the model, the more potential there is for trouble.

You could certainly balance the pros and cons by combining the two methods. For example, you can load the customers and orders with Include and then pull in the order details on an as-needed basis with Load. The correct choice will most likely change on a case-by-case basis.

public static void DeferredLoadingEntityReference() { var addresses = from a in context.Addresses select a; foreach (var address in addresses) { if (address.CountryRegion == "UK") address.ContactReference.Load(); } } public static void EagerLoadWithInclude() { var test = from c in context.Contacts.Include("Addresses") where c.LastName == "Smith" select c; test.OuputTrace(); }