RenderPartial vs RenderAction

ASP.NET MVC website describe pretty well the difference between the two. RenderPartial is used to display a reusable part of within the same controller and RenderAction render an action from any controller. They both render the Html and doesn’t provide a String for output.

Here is a picture that illustrate the difference between RenderPartial and RenderAction in Asp Mvc .Net.

If you need to have a String, which can be the case if you need to return by Ajax the content in Html you should use Html.Partial or Html.Action. They both create the view but instead of rendering it directly into the Http Response will produce an Html string which could be returned to be loaded into a div with Javascript or JQuery.

$('#result').load('http://localhost/myApp/User/Profile/1');

This is a small example where the action Profile of the controller User could return directly a String. To be able to generate this output server side, it would require that the Profile action return ContentResult type that will be generated by Html.Partial or Html.Action.

How to use Linq to query a property that is not in your database but in your class model

One of my team mate would like to query some data with Linq but has always an error message saying that the Linq to Entity couldn’t find the property desired. In fact, the exception was relevant because the property was made up in the model and were using two others properties available from the database.

To figure out more about the problematic let say that in the database you have the field : Id, Name_Fr, Name_En. Let say that in your model you have : Id, Name_Fr, Name_En and also Name. You would like to sort data by name. If you use directly your Entity Framework’s data context to query with Linq To Entity you will get an error because database context will try to do a SQL query with the field Name which doesn’t exist. The solution is to use Linq to Entity to query everything and to sort with Linq to Object.

So, instead of doing :

MyDatabaseContext.MyPeople.OrderBy(c=>c.Name);

You would have to do :

MyDatabaseContext.MyPeople.AsEnumerable().OrderBy(c=>c.Name);

The AsEnumerable() will execute the query which will return a collection of IEnumerable instead of IQueryable. The difference is that MyPeople is IQueryable which doesn’t execute the query until the collection is enumerated (with ForEach for example) or until the query it transformed into a list (for example with ToList()).

The difference between AsEnumerable() and ToList() is concerning performance. The AsEnumerable() is faster if you do subsequent filtering (.Where for example) operation. The reason is that it will filter the query before looping instead of looping the whole collection and then looping to filter.

Entity Framework 4.3 Update a complex object from Asp.Mvc controller

Having to update an object from an edit action is pretty standard. In fact, it’s also very straight forward with basic object (without containing other object).
You could use the FormCollection way to do it:

[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Edit(FormCollection form)
{
    // Get movie to update
    var id = Int32.Parse(form["id"]);
    var movieToUpdate = _db.MovieSet.First(m => m.Id == id);

    // Deserialize (Include white list!)
    TryUpdateModel(movieToUpdate, new string[] { "Title", "Director" }, form.ToValueProvider());

    // If valid, save movie to database
    if (ModelState.IsValid)
    {
        _db.SaveChanges();
    //...
}

Or, you could use the ability of auto binding each http parameters:

[HttpPost]
public ActionResult Edit(Course course)
{
     if (ModelState.IsValid)
     {
         db.Entry(course).State = EntityState.Modified;
         db.SaveChanges();
    //...
}

However, the problem remain that these two examples are only good for object with scalar properties. This mean that it works fine until you have object that reference other object. In real life, you have a lot of change that you will handle complex object that contain reference to many to many others objects or to optional object or to 1 to 1 object.

To be able to handle those scenario, you need to handle scalar data and reference object separately. Here is an example of saving a complex object and its references.

        public void Update(MyObject obj) {
            //Update all but not relationship (scalar properties are updated)
            var fromDatabase = Database.Customers.Where(p=>p.Id==customer.ID);
            Database.Entry(fromDatabase).CurrentValues.SetValues(obj);

            //Update reference
            if (obj.OtherObject!= null) {
                Database.OtherObjects.Attach(obj.OtherObject);
            }
            fromDatabase.OtherObject = obj.OtherObject;

            return Database.SaveChanges();
        }

This check if the reference is null from the form. If yes, it mean that we need to save NULL to be able to have NULL in the foreign key of the database. If not, you need to attach to the Database Context the object (even if this one is not fully loaded, we just need the primary key to be available).

Handling multiple repository with Entity Framework

If you are using 1 dbcontext per repository, you may end by having problem with your reference between each of your object. Let say that you have an object A with an object B and A is handled by RepoA and you change the object B which is handled by the context inside repoB than you won’t have any changes done. This is because the dbcontext contain only reference for RepoA in RepoA and it’s not aware of what has been changed in the other dbcontext in RepoB.

The best way to solve this issue is to share the dbcontext between all your repositories. This can be easily done if you are using a repository factory (Abstract Factory pattern). When you create your repository factory you should create the database context and set it to all repository when they are instantiated.

public class RepositoryFactory : IRepositoryFactory 
{
	private IClassA a;
	private IClassB b;
	private IClassC c;

	private readonly DatabaseContext dbContext;

	public RepositoryFactory()
	{
		this.dbContext = new DatabaseContext();
	}

	public IClassA RepoA 
	{
		get { return a ?? (a = new RepoA(this.dbContext)); }
	}

	public IClassB RepoB 
	{
		get { return b ?? (b = new RepoB(this.dbContext)); }
	}

	public IClassC RepoC 
	{
		get { return c ?? (c = new RepoC(this.dbContext)); }
	}
}

Instead of using your collection .Count() > 0, use .Any()

If you are using a collection : ICollection, IList, List, which doesn’t use enumerator to navigate, the fastest way to check if the collection contain anything is to use .Length or .Count.

But, if you are using IEnumerator<> which contain GetEnumerator() and MoveNext() the fastest way is to use .Any(). The reason is that Any() will do 1 loop and find that it has information so stop looping. If the collection is 10 of size or 9000 of size, both will do 1 loop so the speed is O(1).

LINQ-to-Objects implementation of Count() will call the .Count property for optimisation but if you have used LINQ with WHERE statement or any other Linq filter function, you will have an iterator-block based sequence and this Count() optimisation won’t be applied. In fact, it will loop all the collection to get the count. That mean that the performance is O(n).

To keep it simple, for performance wise and maintenability wise, .Any is the best to use to know if something is inside a list.

Linq to Entity doesn’t load data right after calling the context

Linq to Entity doesn’t execute directly the SQL query to the database when the query is done. This is called Deffered execution.

The SQL will be executed when the code will loop through it with a foreach or if the code use .ToArray(), .ToList(), .ToDictionary() or .ToLookup().

Here is an example, mostly taken from MSDN showing when the data is loaded from the SQL server.

using (AdventureWorksEntities context = new AdventureWorksEntities())
{
    IQueryable<Product> productsQuery = context.Products;
	//productsQuery is not loaded yet
	
    IQueryable<Product> largeProducts = productsQuery.Where(p => p.Size == "L");
	//largeProducts is not loaded yet
    
    foreach (var product in largeProducts) //Execution is here at the beginning of this code
    {
        Console.WriteLine(product.Name);
    }
}

This is a second example where the deferred is not taking long since we are using ToList() which call the database.

using (AdventureWorksEntities context = new AdventureWorksEntities())
{
    var productsQuery = context.Products.Where(p=>p.Size =="L").ToList(); //Executed here
   
}

One advantage is that you can refined the query in a later stage without affecting the performance since it will be executed once. It also let you have the flexibility to build the query in multiple steps. Finally, it let you execute the query at the later stage possible which is good to have the latest version of the data.

Entity Framework 4.3 Poco object relationship zero to many

If you have a relationship of zero to many your master object won’t have in the database any reference to the detail object. It’s the detail object that has foreign key to the master. But, on the C# class side, the master will have a collection of the detail.

To make this work, you need to have a repository that will do the include correctly if you want to use the eager loading.

    MyDbContext.Libraries.Include("Book");

You also need to specify the collection as ICollection. IEnumerator won’t work and if you do, you will end up with an error. This property need to be also virtual.

public virtual ICollection<Book> Books { get; set; }

A specified Include path is not valid. The EntityType ‘DataAccessLayer.Database.Book’ does not declare a navigation property with the name ‘BooksCollection’.

Entity Framework 4.3 and ProxyCreationEnabled

The property ProxyCreationEnabled is by default to True. This property is required to be able to do LazyLoading and also to keep track of changes to the object.

But, in some situation, you may need to set it up to false. One case if to gain on performance. Entity Framework will generate a proxy class which contain some overhead that will contains the previous state of the the object. Furthermore, creating object with proxy make them not serializable. Finally, some controls like Telerik suite (version 2012.1.214.340), cannot be bind to proxy classes.

To set the DbContext to false for proxy, you need to set the property Configuration.ProxyCreationEnable = false. This property is available to any DbContext object.

The model backing the context has changed since the database was created, EF4.3/5.0

Entity Framework version 4.35.0 (and since 4.1) can throw the exception that the model and the database cannot be mapped correctly. In fact, EF is saying that the model has changed since the database has been created.

The model backing the ‘MyContext’ context has changed since the database was created. Consider using Code First Migrations to update the database (http://go.microsoft.com/fwlink/?LinkId=238269)

To resolve this problem, you will find on the Web a lot of solution but most of them work with previous version of Entity Framework 4.35.0.

The solution from this version is to use the static method SetInitializer and bind to the context a Null value. If you are working on a Web solution, the best position to write the code is in the Application_Start of your Global.asax.cs file.

protected void Application_Start() 
{
    AreaRegistration.RegisterAllAreas();
    RegisterRoutes(RouteTable.Routes);
    //...
    Database.SetInitializer<MyContext>(null);
}

Using this code remove the error and let you handle manually the creation of the database.

Entity Framework 4.3 without ObjectStateManager, how to verify if an object changed?

Previously, few months ago, it was possible to access the ObjectStateManager and to use the method GetObjectStateEntry with the object desired to get the state.

Customer customer = //...
ObjectStateEntry ose = context.ObjectStateManager.GetObjectStateEntry(customer);
Console.WriteLine("Customer object state: {0}", ose.State); 
customer.Country = "USA";
Console.WriteLine("Customer object state: {0}", ose.State); 

The version of EF4.3 doesn’t have the ObjectStateManager available. It’s possible to get the state but with the property ChangeTracker.

To see a specific object state you will need this property, the ChangeTracker, with a Linq query.

var e = dbContext.ChangeTracker.Entries<Customer>().Single(p=>p.Entity == myCustomer);
Console.WriteLine("Customer state: " + e.State);

ChangeTracker.Entries can be generic has the example above or not. In both case, it returns a lit of objects that is listened by the tracker. It doesn’t mean that all objects inside the tracker has changed. The Linq query, with the Single() method, will search to get a Single correspondence to your object by comparing the Entity inside the Entry list to the customer that is wanted to get the state.