无法将'DAL Class'类型的对象强制转换为'BLL Class'

时间:2016-01-14 17:47:18

标签: c#

我遇到了将DAL级别课程的结果“转发”到同一定义的BLL课程的问题。

错误:“无法将'DeserializedGame'类型的对象强制转换为'DeserializedGameBLL'。”

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

我需要做些什么才能使我的DeserialzedGame集合正常工作?

我查看了this question(并尝试在原帖中关注@Measuring建议)。我考虑过(并且仍然没有消除using DTO's,但我不确定如何正确使用它们。)

如果这属于Code Review部分,我会很乐意在那里发帖,但我认为有些人可能会遇到同样的挫折感。

2 个答案:

答案 0 :(得分:1)

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

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

[基于对上述问题的评论...]看来你有这样的架构:

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

所以发生了什么:

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

只是谈论它让它听起来很头疼:))

相反,请考虑稍微修改一下的架构:

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

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

这并不是说此设置理想。在许多情况下,我甚至会争辩说这个共同的DTO&#34;方法可以快速成为反模式,并且是适当的域驱动架构的不良替代品。 但是,我对这些事情总是有点纯粹主义。我的论点取决于业务层不引用任何内容而数据层引用业务层的想法。除非你熟悉依赖倒置模式和技术,否则对你来说很难。

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

答案 1 :(得分:0)

您可以使用Automapper等库,也可以使用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运算符进行操作,以便不需要强制转换。