Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does Entity Framework/LINQ to SQL Data Binding use reflection?

Forgive me if this has been asked before; I did a search but couldn't find anything that specifically answered this question, but I'd be happy to be referred.

I'm taking a peek at both the Entity Framework and LINQ to SQL, and while I like the systems (and of course the LINQ integration) I'm a little skeptical on the data-binding aspect. I've taken query results and inspected them, and they don't appear to implement the standard .NET list-binding interfaces (IBindingList, and more importantly ITypedList), leading me to believe that binding them to a grid (or anything else) is going to use reflection to get/set my entity properties. This seems like a comparatively expensive operation, especially when all of the code is generated anyway and could implement the interfaces.

Does anyone have any insight into this? Is reflection used to get/set the value of the properties? If yes, does this have a performance impact that's noticeable, and does anyone have any idea why they went this route?

Edit

I'm actually concentrating on whether or not ITypedList is implemented somewhere along the way, as that's what has the capability to provide an explicit mechanism for defining and interacting with properties without resorting to reflection. While I didn't have a LINQ to SQL project up, I did inspect a simple Entity Framework entity query result, and it did not appear to implement ITypedList. Does anyone know if I'm just looking at something incorrectly, or if not why this is the case?

Edit 2

After accepting Marc's answer, I thought it might be helpful for others if I posted some simple code I used to seamlessly implement his solution. I put the following in the static constructor for my class:

public static ContextName()
{
    foreach(Type type in System.Reflection.Assembly.GetExecutingAssembly()
        .GetTypes())
    {
        if (type.GetCustomAttributes(typeof(System.Data.Linq.Mapping
            .TableAttribute), true) != null)
        {
            System.ComponentModel.TypeDescriptor.AddProvider(
                new Hyper.ComponentModel.HyperTypeDescriptionProvider(
                    System.ComponentModel.TypeDescriptor.GetProvider(
                        type)), 
                type);
        }
    }
}

While this is for LINQ to SQL, I'm sure an equivalent version could be written for the Entity Framework. This will scan the assembly for any types with the Table attribute and add a custom provider for each of them.

like image 706
Adam Robinson Avatar asked Apr 20 '09 00:04

Adam Robinson


2 Answers

The Expression API that underpins LINQ etc is founded on reflection (MemberInfo), not the component-model (PropertyDescriptor etc) - so there is not a huge requirement for ITypedList. Instead, the contents are inferred from the T in IQueryable<T>, IEnumerable<T> and IList<T> etc.

The closest you might get is IListSource, but that will still just be a shallow wrapper around a proper typed list.

If performance of runtime binding (to PropertyDescriptor) is key, you might want to look at HyperDescriptor - which uses Reflection.Emit and TypeDescriptionProvider to wrap the component-model.

Re the "why" etc; note that in almost all cases with LINQ-to-SQL and EF the Expression (or the "create and set members" part) is going to be compiled to a delegate before it is invoked - so at runtime there is no huge reflection cost. And likewise, with LINQ-to-Objects everything is already compiled (by the C# compiler).

like image 185
Marc Gravell Avatar answered Oct 21 '22 08:10

Marc Gravell


In my experience with LINQ to SQL, I have concluded for a few reasons that LINQ is using reflection to set and get field values in entity class instances. I don't know if I can remember all the reasons, but here's what I can tell you.

  1. If I recall correctly, LINQ does not call any property procedures, but directly sets and reads all the private field values directly, which can only be done via reflection, as far as I know.
  2. The names provided by the MetaData (in the attributes on the entity class properties) provide field name information in string form (if the database column and property name are different, for example). You can conclude from this that LINQ must be using reflection to look up the member to access it.

I think it does this to enforce simplicity -- you can rely on the values in the fields in the entity class directly mirroring the database column values, and there's not much overhead in retrieving the object from the database (populating a newly created entity to correspond to values retrieved from the database should not be routed through property procedures). One thing I have done to represent enumerated values retrieved from the database, for example, is to make some of the LINQ-generated properties private and wrap them in a manually coded property in a partial class that reads and writes the LINQ property.

like image 34
BlueMonkMN Avatar answered Oct 21 '22 07:10

BlueMonkMN