Casting DbSet<Entity> to its DbSet<IEntity> without pulling all entities to memory
c#, entity-framework, linq
Solution
`IQueryable<T>` is covariant so instead of attempting to cast the `DbSet<SubType>` to `DbSet<SuperType>`, simply assign:
Data = context.Set<Entity>(); // .AsQueryable() not needed but does make it more readable
This, of course, depends on `Entity` implementing `C1Data`, which is not guaranteed based on your generic class definition (which is not good). To fix this, change your type constraint for `Entity` as follows:
where Entity: C1Data
Problem
My Problem is that the system I am working with expects Data as `IQuearable<IEntity>` and entityframework gives me data as `IQueryable<Entity>` This is from an interface I need to implement: ``` public IQueryable<T> GetData<T>() where T : class, IData {} ``` I have a DbSet created as context.Set(MyEntityType), where MyEntityType is typeof(Entity). I have been trying a few things by now and not sure how I will get around this. (its all auto generated code from codedom, but made a test below to see that it can work, but havent got things working) I made a wrapper for testing and the problem is here `LINQ to Entities only supports casting EDM primitive or enumeration types` If I can make this work I can make my other parts work also. ``` public class DbSetWrapper<C1Data,Entity> where C1Data : IData where Entity: class { public DbSetWrapper(C1AzureStoreRPContext context) { Data = context.Set<Entity>().Cast<C1Data>(); } public IQueryable<C1Data> Data { get; private set; } } public class C1AzureStoreRPContext : DbContext { static C1AzureStoreRPContext() { Database.SetInitializer<C1AzureStoreRPContext>(null); } // Methods public C1AzureStoreRPContext(string connectionstring) : base(connectionstring) { } // Properties public DbSet<AzureStoreSubscriptionWrapper> AzureStoreSubscriptions { get; set; } } public interface IAzureStoreSubscription : IData, IEntityFrameworkProvided {} public class AzureStoreSubscriptionWrapper : AzureStoreSubscription, IAzureStoreSubscription { } using (var c1 = new C1AzureStoreRPContext("opencms-sql-connection")) { var wrap = new DbSetWrapper<IAzureStoreSubscription, AzureStoreSubscriptionWrapper>(c1); Log.LogInformation("EF", string.Format("hello {0}", wrap.Data.ToList().Count)); } ``` I don't want to pull all the data to memory and do the cast their, is there no other solution?