score:0

Depending on how many classes we're talking about, and how flexible you need to be, interfaces might not be out of the question. I've done something similar using generics:

//WARNING: Partially-remembered code ahead...
interface IDuckEntity
{
    int FeatherCount { get; set; }
}

public partial class Products1 : IDuckEntity { }
public partial class Products2 : IDuckEntity { }
public partial class Products3 : IDuckEntity { }

//in some other class:
void DoStuff<T>(T entity) where T : EntityObject, IDuckEntity
{
     entity.FeatherCount = 500;
}

So basically, you set up a separate file where you put the interface and a bunch of those little partial class declarations. Then you'll have access to the common structure. I don't know what your exact situation is, but this worked like a charm for me.

score:1

Since the EF4 classes are partial classes you can actually extend them and make them implement an interface of your choice, all in a separate file.

An alternative to that would be using dynamic - just instantiate the entity based on it's type.

dynamic myEntity= Activator.CreateInstance(Type.GetType("EntityTypeHere")));
myEntity.CommonProperty = "Foo";

The big disadvantage here is that you lose all type safety at compile time - any problem you will only discover at runtime, also it's slower than the statically typed approach.

score:2

You could build an Expression tree to query for the object or objects in question:

public T GetSingleObject<T>(int someValue) {
    MyEntities db = new MyEntities();
    var result = db.CreateQuery<T>(String.Format("[{0}]", typeof(T).Name + "s"));

    var param = Expression.Parameter(typeof(T));

    var lambda = Expression.Lambda<Func<T, bool>>(
        Expression.Equal(
            Expression.Property(param, "WhateverPropertyYourComparing"),
            Expression.Constant(someValue)),
        param);

    return result.SingleOrDefault(lambda);
}

Or if you want a collection of objects

public IEnumerable<T> GetResultCollection<T>(int someValue) {
    MyEntities db = new MyEntities();
    var result = db.CreateQuery<T>(String.Format("[{0}]", typeof(T).Name + "s"));

    var param = Expression.Parameter(typeof(T));

    var lambda = Expression.Lambda<Func<T, bool>>(
        Expression.Equal(
            Expression.Property(param, "WhateverPropertyYourComparing"),
            Expression.Constant(someValue)),
        param);

    return result.Where(lambda);
}

Of course if your desired query is very long, this can get out of hand, and you should consider adding in the necessary interface using partial classes, as Justin Morgan suggested.

Note that this method assumes that your ObjectSet collection is the same name as your object, plus an "s", ie, "Invoice" to "Invoices". If that's not the case, ie, "Person" to "People", then you could use System.Data.Entity.Design.PluralizationServices.PluralizationService to get the proper name


Related Articles