【问题标题】:Entity Framework Core - Inherited Object Types and Dynamic Table NamesEntity Framework Core - 继承的对象类型和动态表名
【发布时间】:2020-06-08 08:18:15
【问题描述】:

我有一个分区表列表。这些表有很多,但结构相同。意识到 EF 核心需要不同的类型来处理这些,但最终我想对数据使用通用类型转换,这样可以更轻松地处理数据。与 Oracle 合作,但认为问题一般适用。

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

System.InvalidCastException: '无法转换类型为'Microsoft.EntityFrameworkCore.Internal.InternalDbSet1[EfCoreBidTest.BidPhaseLh2]' to type 'Microsoft.EntityFrameworkCore.DbSet1[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);
    }

【问题讨论】:

    标签: c# oracle entity-framework-core


    【解决方案1】:

    DbSet&lt;BidPhase&gt; 是与 DbSet&lt;BidPhase2&gt; 完全不同的类型,即使泛型类型相互继承 - DbSet&lt;&gt; 不是 covariant。一种解决方法是使用IQueryable&lt;&gt; 而不是DbSet&lt;&gt;。例如:

    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;
    }
    

    【讨论】:

    • 是否允许我进行更新(或仅选择调用)?
    • 那时你没有办法做你想做的事。您不能将 DbSet&lt;X&gt; 强制转换为 DbSet&lt;Y&gt;
    • 接口的 DbSet 怎么样
    • @Ctznkane525 你不需要DbSet 进行更新 - DbContext 提供了使用更改跟踪器的所有方法 - Attach, Add, Update, Remove + 他们RangeAsync 版本。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-03-06
    • 1970-01-01
    • 2021-10-19
    • 1970-01-01
    • 1970-01-01
    • 2020-08-31
    • 2014-08-20
    相关资源
    最近更新 更多