实体框架核心-继承的对象类型和动态表名称

时间:2020-02-24 16:41:52

标签: c# oracle entity-framework-core

我有一个分区表列表。这些表很多,但结构相同。意识到EF核心为此需要不同的类型,但最终我想对数据使用通用类型转换,这将使处理数据更加容易。与Oracle合作,但认为问题会普遍适用。

这是错误。基本上我想将T的DbSet强制转换为S的DbSet,其中S是T的父类。

System.InvalidCastException:'无法转换类型为'Microsoft.EntityFrameworkCore.Internal.InternalDbSet 1[EfCoreBidTest.BidPhaseLh2]' to type 'Microsoft.EntityFrameworkCore.DbSet 1 [EfCoreBidTest.BidPhase]'的对象。'

请记住,我将在同一基础上同时处理多个继承的类型。

这是一个基类示例:

using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using System.Text;

namespace EfCoreBidTest
{
    public class BidPhase
    {
        [Column("YR")]
        public int Yr { get; set; }

        [Column("QTR")]
        public string Qtr { get; set; }

        [Column("AMB_CODE")]
        public string AmbCode { get; set; }

        [Column("SECT")]
        public string Sect { get; set; }

        [Column("PHASE_ITEM")]
        public int PhaseItem { get; set; }

        [Column("PHASE")]
        public string Phase { get; set; }

        [Column("PHASE_DATE")]
        public DateTime? PhaseDate { get; set; }
    }
}

和一个继承的类(其中有很多)

using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations.Schema;
using System.Text;

namespace EfCoreBidTest
{
    [Table("BID_LH2_MASTSTAT_PHASE")]
    public class BidPhaseLh2 : BidPhase
    {
    }
}

尝试在DbContext上创建通用方法以获取阶段对象类型,也就是我收到错误的时间

    public DbSet<BidPhase> GetPhaseSet(string sys, string stage)
    {

        var t = typeof(BidDatabase);

        var setMethod = t.GetMethod("Set");
        var setMethodSpecific = setMethod.MakeGenericMethod(new Type[] { typeof(BidPhaseLh2) }); // TO DO - This will eventually get replaced with something to get the type based on the assembly name
        var dbSet = setMethodSpecific.Invoke(this, null);
        return (DbSet <BidPhase> ) dbSet;


        //sys = Char.ToUpper(sys[0]) + sys.Substring(1).ToLower();
        //return (IQueryable<BidPhase>) this.GetType().GetProperty("BidPhase" + sys + stage).GetValue(this);
    }

1 个答案:

答案 0 :(得分:1)

DbSet<BidPhase>DbSet<BidPhase2>是完全不同的类型,即使泛型类型彼此继承-DbSet<>不是covariant。解决此问题的一种方法是使用IQueryable<>而不是DbSet<>。例如:

public static IQueryable<BidPhase> GetPhaseSet(BidDatabase ctx)
{
    var t = typeof(BidDatabase);

    var setMethod = t.GetMethod("Set");
    var setMethodSpecific = setMethod.MakeGenericMethod(new Type[] { typeof(BidPhaseLh2) }); 
    var dbSet = setMethodSpecific.Invoke(ctx, null);
    return (IQueryable<BidPhase>)dbSet;
}