Entity Framework 4

Fixing MVC 3 Html.DropDownListFor selected item

I recently ran into an issue with when using the SqlFunctions.StringConvert function (as required by LINQ to cast scalars to a string). What I didn’t realize at first is that the StringConvert function pads the string that it casts to. As it turns out this causes some issues with defining a selected item in the list.

To best describe this issue it is probably best to quickly walk through an example of how I ran into this and resolved it.

The Problem

The editor is to provide a drop down list of available options for a given property on the Entity being edited. In my case this was a POCO being used with the Entity Framework. Straight forward enough. I started with the following in my view model.

public class foo
{
  public MyObject MyObject { get; private set; }
  public List MyObjects{ get; private set; }

  public foo(int id){
    this.MyObject = MyObjectRepository.GetById(id);
    this.MyObjects = (from c in MyObjectRepository.All
                      where c.Id != id
                      select new SelectListItem {
                        Text = c.Name,
                        Value = SqlFunctions.StringConvert((double)c.Id)
                      })
                      .ToList());

  }
}

In my view I had the following code.

 @Html.DropDownListFor(m=>m.MyObject.ParentID, Model.MyObjects)

MyObject has a property that references its parent, if it has one. This is the trigger for our selected item.

Upon running this code I quickly noticed that the parent was not being selected. I looked and the LINQ statement was getting the correct ID’s and the ParentID was correct. So what was happening?

Well as it turns out the StringConvert functions casts the Id to a padding string and adding a call to the Trim function fixed everything. This is definitely a bit clunky in my opinion. Why did the LINQ team not let us simply cast our scalars using the ToString function?

Well that is it, below is the final LINQ statement that worked for me.

    this.MyObjects = (from c in MyObjectRepository.All
                      where c.Id != id
                      select new SelectListItem {
                        Text = c.Name,
                        Value = SqlFunctions.StringConvert((double)c.Id).Trim()
                      })
                      .ToList());

Related Posts:

  • No Related Posts

EF 4.2 Update POCO with ObjectContext

I recently worked on a project that used the Entity Framework and T4 POCO generation. I ran into a little snag during the implementation of the Repository pattern that took a few minutes for me to figure so I thought that I would save someone else the time and share here.

First let’s start off with the Interface.

  public interface IRepository : IDisposable
  {
    IQueryable All { get; }
    T GetById(int id);
    void Add(T model);
    void Update(T model);
    void Delete(T model);
    void Save();
  }

Next we’ll look at my first try at the concrete implementation of the Update method. The DataContext is a private property containing a reference to the object context object.

  public class MyRepository : IRepository
  {
    public IQueryable All { get{...} }
    public MyEntity GetById(int id) {...}
    public void Add(MyEntity model) {...}

    public void Update(MyEntity model)
    {
      DataContext.Users.Attach(model);
      if (model.Id == null )
      {
        // no UserId denotes new object to the database.
        DataContext.ObjectStateManager.ChangeObjectState(model, System.Data.EntityState.Added);
      }
      else
      {
        // object is not new. We need to get the original object and apply original values.
        // Applying current or original values, changes the state
        // of the attached object to Modified.
        var originalObject = GetById(model.UserId);
        DataContext.ApplyCurrentValues("MyEntities", originalObject);
      }

      Save();

    }

    public void Delete(MyEntity model) {...}
    public void Save() {...}
  }

Everything looked good to me so I ran a quick test set. To my surprise the Update method was failing. Why would this be? Well as it turns out since I was generating my POCO’s I needed to set the EntityState to Modified manually. So added the line below after the ApplyCurrentValues call.

DataContext.ObjectStateManager.ChangeObjectState(model, System.Data.EntityState.Modified);

I fired up the test cases once again and was happy to see all tests passed.

Well that is it, I hope that this post helps you and others in the future.

Related Posts:

  • No Related Posts