开发者

how to convert the <T> to its base type for generic method?

I have a generic CRUD class to perform add, delete, select, create to my entity objects.

one of them - Message has two derived classes - order_message , and report_message.

My problem is that in my generic class, I need an objectset to perform crud ops, but objectset does not accept a derived class type, it only accept开发者_高级运维 base class type.

This is the error I received:

There are no EntitySets defined for the specified entity type 'CustomerWebPortal_Entities.Order_Message'. If 'CustomerWebPortal_Entities.Order_Message' is a derived type, use the base type instead.

I tried use typeof(T).BaseType to replace T, and of cause was not working.

How should I correct this?

This is the overview of the generic class:

 public abstract class baseCrudDao<T> : ICrudDao<T> where T : class
{
    private System.Data.Objects.ObjectContext _context;

    private System.Data.Objects.ObjectSet<T> _entity; 
    public baseCrudDao()
    {

        _context = new CustomerWebPortalEntities();
        _entity = _context.CreateObjectSet<T>(); <-- error at here, only accept base type

    }


Well I finally had a chance to write a prototype as suggested. I think that something like this would work but I haven't tested it. Now all of your crud methods can be defined against the IObjectSet<> member.

public class Crud<EntityType> where EntityType : class
{
    private readonly ObjectContext Context;
    private readonly IObjectSet<EntityType> Entities;

    public Crud(ObjectContext context)
    {
        Context = context;

        Type BaseType = GetBaseEntityType();

        if (BaseType == typeof(EntityType))
        {
            Entities = Context.CreateObjectSet<EntityType>();
        }
        else
        {
            Entities = (IObjectSet<EntityType>)Activator.CreateInstance(typeof(ObjectSetProxy<,>).MakeGenericType(typeof(EntityType), BaseType), Context);
        }
    }

    private static Type GetBaseEntityType()
    {
        //naive implementation that assumes the first class in the hierarchy derived from object is the "base" type used by EF
        Type t = typeof(EntityType);

        while (t.BaseType != typeof(Object))
        {
            t = t.BaseType;
        }

        return t;
    }
}

internal class ObjectSetProxy<EntityType, BaseEntityType> : IObjectSet<EntityType>
    where EntityType : BaseEntityType
    where BaseEntityType : class
{
    private readonly IObjectSet<BaseEntityType> Entities;

    public ObjectSetProxy(ObjectContext context)
    {
        Entities = context.CreateObjectSet<BaseEntityType>();
    }

    public void AddObject(EntityType entity)
    {
        Entities.AddObject(entity);
    }

    //TODO: implement remaining proxy methods

    public IEnumerator<EntityType> GetEnumerator()
    {
        return Entities.OfType<EntityType>().GetEnumerator();
    }

    System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
    {
        return GetEnumerator();
    }

    public Type ElementType
    {
        get { return typeof(EntityType); }
    }

    public Expression Expression
    {
        get { return Entities.OfType<EntityType>().Expression; }
    }

    public IQueryProvider Provider
    {
        get { return Entities.Provider; }
    }
}


One work-around will be to use two generic type parameters (on base class) such as

public abstract class baseCrudDao<T, U> : ICrudDao<T> where U : class, T: U
{
    ...
    public baseCrudDao()
    {
        _context = new CustomerWebPortalEntities();
        _entity = _context.CreateObjectSet<U>(); <-- error at here, only accept base type
    }
    ...
}

Use Message in place of U. If you have many types and not all have inheritance relationships then constraint T:U won't work and you need to perhaps use T:class constraint. I will also suggest that you create another skeleton base class to be used for other types such as

public abstract class base2CrudDao<T> : baseCrudDao<T, T>

so that you don't have to specify U parameter for classes that don't have inheritance relationship.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜