无法将类型为“DAL 类”的对象强制转换为类型“BLL 类”

本文关键字:类型 转换 BLL 对象 DAL | 更新日期: 2023-09-27 18:30:35

我在将 DAL 级别类的结果"结转"到相同定义的 BLL 类时遇到问题。

错误:"无法将类型为'反序列化游戏'的对象强制转换为类型'反序列化游戏 BLL'。

//DAL Classes
public class GameCollection{
    public List<DeserializedGame> Games { get; set; }
    public int RefreshInterval { get; set; }
    public string CurrentDate { get; set; }
    public string NextDate { get; set; }
    public string PrevDate { get; set; }
}
public class DeserializedGame
{
    public string Atcommon { get; set; }
    public string Canationalbroadcasts { get; set; }
    public string Ata { get; set; }
    public bool Rl { get; set; }
    public int Atsog { get; set; }
    public string Bs { get; set; }
    public string Htcommon { get; set; }
    public int Id { get; set; }
    public string Atn { get; set; }
    public int Hts { get; set; }
    public string Atc { get; set; }
    public string Htn { get; set; }
    public string Usnationalbroadcasts { get; set; }
    public bool Gcl { get; set; }
    public string Hta { get; set; }
    public int? Ats { get; set; }
    public string Htc { get; set; }
    public int Htsog { get; set; }
    public string Bsc { get; set; }
    public int Gs { get; set; }
    public bool Gcll { get; set; }
}
//BLL Classes
public class GameCollectionBLL : IEnumerable
{
    public List<DeserializedGame> Games { get; set; }
    public int RefreshInterval { get; set; }
    public string CurrentDate { get; set; }
    public string NextDate { get; set; }
    public string PrevDate { get; set; }
    public GameCollectionBLL(List<DeserializedGame> gameList, int refreshInterval, string currentDate,
        string nextDate, string previousDate)
    {
        this.Games = gameList;
        this.RefreshInterval = refreshInterval;
        this.CurrentDate = currentDate;
        this.NextDate = nextDate;
        this.PrevDate = previousDate;
    }
    public IEnumerator GetEnumerator()
    {
        return (Games as IEnumerable).GetEnumerator();
    }
}
public class DeserializedGameBLL : BaseSeasonSchedule
{
    public string Atcommon { get; set; }
    public string Canationalbroadcasts { get; set; }
    public string Ata { get; set; }
    public bool Rl { get; set; }
    public int Atsog { get; set; }
    public string Bs { get; set; }
    public string Htcommon { get; set; }
    public int Id { get; set; }
    public string Atn { get; set; }
    public int Hts { get; set; }
    public string Atc { get; set; }
    public string Htn { get; set; }
    public string Usnationalbroadcasts { get; set; }
    public bool Gcl { get; set; }
    public string Hta { get; set; }
    public int? Ats { get; set; }
    public string Htc { get; set; }
    public int Htsog { get; set; }
    public string Bsc { get; set; }
    public int Gs { get; set; }
    public bool Gcll { get; set; }
}
public abstract class BaseSeasonSchedule
{
    public int GameID { get; set; }
    public DateTime GameDate { get; set; }
}
//UI usage
public partial class Form1 : Form
{
    private SeasonSheduleBLL objSeasonSchedule = new SeasonSheduleBLL();
    private void button1_Click(object sender, EventArgs e)
    {
            GameCollectionBLL gameDay = objSeasonSchedule.GetGameCollection(json_string);
            foreach (DeserializedGameBLL game in gameDay)  //error occurs here when referencing the DeserialzedGameBLL
                    {
                        // do stuff here
                    }
    }
}

我需要做什么才能使我的反序列化游戏集合正常工作?

我已经看过这个问题(并试图遵循原始帖子中的@Measuring建议)。 我已经考虑过(并且仍然没有使用 DTO 消除,但我不确定如何正确使用它们)。

如果这属于代码审查部分,我会很乐意在那里发布,但我认为有足够多的人可能会经历和我一样的挫败感。

无法将类型为“DAL 类”的对象强制转换为类型“BLL 类”

该错误只是告诉您不能在两个不相关的类型之间进行隐式转换。 仅仅因为它们看起来相同并不意味着它们是相同的类型。 若要更正此问题,必须创建目标类型的实例,并将所有数据从源对象复制到目标对象。 (或者使用像Automapper这样的库来做同样的事情。

然而,这确实引出了一个问题...为什么首先有相同的类型?

[根据对上述问题的评论...]您似乎有这样的体系结构:

  • 应用层引用业务层。
  • 业务层引用数据层。
  • 数据层不引用任何内容。

所以正在发生的事情是:

  • 数据层具有一种类型,因此它可以具体化数据库中的数据。
  • 业务层从数据层获取该对象。
  • 应用程序层需要该对象,但不能引用数据层。 因此,业务层需要将数据层对象转换为应用层可以接收的业务层对象。

光是说起来就让人头疼:)

相反,请考虑稍微修改的体系结构:

  • 公共库包含 DTO(以及接口和其他常见类型),但没有有意义的逻辑,并且不引用任何内容。
  • 应用层引用业务层和公共库。
  • 业务层引用数据层和公共库。
  • 数据层引用公共库。

现在,数据层返回的对象可以一直到应用程序层而无需修改,因为每个层都了解该类型。

这并不是说这种设置是理想的。 在许多情况下,我甚至会争辩说,这种"通用 DTO"方法很快就会成为一种反模式,并且是适当的领域驱动架构的糟糕替代品。 但是,我一直对这些事情有点纯粹。 我的论点取决于业务层不引用任何内容,数据层引用业务层的想法。 除非您熟悉依赖关系反转模式和技术,否则这对您来说将是困难的。

在这种简单的 3 层垂直架构的简单情况下,拥有一个通用库可以非常方便地避免这个确切的问题。

您可以使用自动映射器等库,也可以使用 explicit 关键字自己执行此操作。

public class DeserializedGame
{
    public string Atcommon { get; set; }
    public string Canationalbroadcasts { get; set; }
    public string Ata { get; set; }
    public bool Rl { get; set; }
    public int Atsog { get; set; }
    public string Bs { get; set; }
    public string Htcommon { get; set; }
    public int Id { get; set; }
    public string Atn { get; set; }
    public int Hts { get; set; }
    public string Atc { get; set; }
    public string Htn { get; set; }
    public string Usnationalbroadcasts { get; set; }
    public bool Gcl { get; set; }
    public string Hta { get; set; }
    public int? Ats { get; set; }
    public string Htc { get; set; }
    public int Htsog { get; set; }
    public string Bsc { get; set; }
    public int Gs { get; set; }
    public bool Gcll { get; set; }
    public static implicit operator DeserializedGameBLL(DeserializedGame game)
   {
       return new DeserializedGameBLL()
       {
           pubAtcommon = pubAtcommon,
           Canationalbroadcasts= Canationalbroadcasts,
           Ata = Ata ,
           Rl = Rl ,
           Atsog = Atsog ,
           Bs = Bs ,
           Htcommon = Htcommon ,
           Id = Id ,
           Atn =Atn ,
           Hts =Hts ,
           Atc =Atc ,
           Htn =Htn,
           Usnationalbroadcasts =Usnationalbroadcasts,
           Gcl =Gcl,
           Hta =Hta,
           Ats =Ats,
           Htc =Htc,
           Htsog = Htsog,
           Bsc = Bsc,
           Gs = Gs,
           Gcll = Gcll 
        };
    }
}

你可以像这样使用它:

DeserializedGame b = new DeserializedGame();
DeserializedGameBLL c = b;

您还可以使用 explicit 运算符并制作它,这样如果您不想自动转换,您也不需要强制转换。