Rob Bowman
Rob Bowman

Reputation: 8711

Cannot implicitly convert type DbSet

I have a context that contains many DbSets. Some of these DbSets implement an interface called IActivity which contains a number of common fields such as TimeReceived, TimeSent.

In my controller, I need to read values from one of the context DbSets but I don't know which one until runtime. So I created the following FactoryClass:

public static class ActivityFactory
{
    public static DbSet<IActivity> GetDbSet(BAMContext context, BizTalkApplicationEnum previousApplication)
    {
        switch (previousApplication)
        {
            case BizTalkApplicationEnum.Erp:
                return context.ErpRecs;
            case BizTalkApplicationEnum.Scip:
                return context.ScipRecs;
        }
        return null;
    }
}

The IActivity interface is defined as follows:

public interface IActivity
{
    string ActivityID { get; set; }
    string InterchangeId { get; set; }
    DateTime LastModified { get; set; }
    DateTime? TimeReceived { get; set; }
    DateTime? TimeSent { get; set; }
    string RoutingSource { get; set; }
    string RoutingTarget { get; set; }
    string RoutingToClient { get; set; }
    string RoutingMaster { get; set; }
    string ReceivePort { get; set; }
    string SendPort { get; set; }
    string RoutingMessageType { get; set; }
}

... and the BAM Context:

public class BAMContext : DbContext
{
    public BAMContext()
        : base("BAMPrimaryImportConString")
    {
        this.Configuration.LazyLoadingEnabled = false;
        Database.SetInitializer<BAMContext>(null);
    }
    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
    }

    public virtual DbSet<Erp> ErpRecs { get; set; }
    public virtual DbSet<Scip> ScipRecs { get; set; }
}

My problem is, I get the following compilation error: on the return statements within the case:

Error   CS0029  Cannot implicitly convert type 'System.Data.Entity.DbSet<TVS.ESB.BamPortal.DomainClasses.BAM.Erp>' to 'System.Data.Entity.DbSet<TVS.ESB.BamPortal.DomainClasses.BAM.IActivity>'

Could anyone please let me know how I can solve this problem?

Upvotes: 2

Views: 3492

Answers (2)

Alexander Derck
Alexander Derck

Reputation: 14498

You should be able to work with a generic constraint:

public static class ActivityFactory
{
public static DbSet<T> GetDbSet<T>(BAMContext context, 
             BizTalkApplicationEnum previousApplication) where T: class, IActivity
{
    switch (previousApplication)
    {
        case BizTalkApplicationEnum.Erp:
            return context.ErpRecs;
        case BizTalkApplicationEnum.Scip:
            return context.ScipRecs;
    }
    return null;
}
}

Your next problem will be accessing the properties from IActivity on the dbset you get back though, maybe my answer here can help you with that.

Upvotes: 3

Ilya Chumakov
Ilya Chumakov

Reputation: 25019

I think it is not possible and you cann't convert DbSet<Foo> to DbSet<IFoo>.

The workaround may be to choose right DbSet first and materialize the data (execute the query). Then you can create new list List<IActivity> from a List<Erp> or List<Scip> using a covariance feature: Cast List<T> to List<Interface>

Upvotes: 1

Related Questions