C# dbcontext 不断返回 null 尽管数据库中有数据

问题描述 投票:0回答:2

我有一个 API 端点,如图所示:

[HttpGet("{language}")]
public async Task<IActionResult> GetAllClozeWords(string language)        
{
    var clozes = await GetClozesForLanguage<Cloze>(language);
    
    if (clozes.IsNullOrEmpty())
    {
        return BadRequest();
    }
 
    return Ok();
}

private async Task<List<T>> GetClozesForLanguage<T>(string language) where T : Cloze 
{
    switch (language.ToLower())
    {
        case "nl":
            return await this._trackerDbContext.NLclozes.ToListAsync() as List<T>;

        case "en":
            return await this._trackerDbContext.ENclozes.ToListAsync() as List<T>;

        default:
            return new List<T>();
    }
}

以及如图所示的实体框架模型:

public abstract class Cloze
{
    public int Id { get; set; }
    public string cloze_word { get; set; }
}

public class NLcloze : Cloze
{
    public string note1 { get; set; }
    public string note2 { get; set; }
    public string note3 { get; set; }
    public virtual ICollection<NLexpression> NLexpressions { get; set; }
    public virtual ICollection<ENcloze> ENclozes { get; set; }
}

public class ENcloze : Cloze
{
    public string note1 { get; set; }
    public string note2 { get; set; }
    public string note3 { get; set; }
    public virtual ICollection<ENexpression> ENexpressions { get; set; }
    public virtual ICollection<NLcloze> NLclozes { get; set; }
}

当我使用带有适当

language
参数的 get 请求到达端点时,例如
nl
,尽管我已经仔细检查过数据库中是否有数据,但我在 switch 语句的返回中一直得到 null。

有人知道我哪里错了吗?

c# entity-framework
2个回答
0
投票

这可能不是最佳答案,我无法发表评论,但希望对您有所帮助:

“ToListAsync()”是否真的带回了任何数据?如果是这样,问题将出在铸造上。如果没有,您可能正在寻找其他问题,例如与数据库的连接。

因此将函数更改为 ,看看您是否从数据库中得到了任何东西。

private async Task<List<T>> GetClozesForLanguage<T>(string language) where T : Cloze 
{
    switch (language.ToLower()){
        case "nl":
            var nl = await this._trackerDbContext.NLclozes.ToListAsync();
            return nl as List<T>;
        case "en":
            var en = await this._trackerDbContext.ENclozes.ToListAsync();
            return en as List<T>;
        default:
            return new List<T>();
    }
}

0
投票

我会说这里不需要通用实现,可能会让您感到悲伤。至少你应该用断点检查你的

case
场景是否被命中以及读取的值是否符合你的期望。

也就是说,继承不需要泛型转换:

private async Task<List<Cloze>> GetClozesForLanguage(string language) 
{
    switch (language.ToLower())
    {
        case "nl":
            return await _trackerDbContext.NLclozes.ToListAsync();

        case "en":
            return await _trackerDbContext.ENclozes.ToListAsync();

        default:
            return new List<Cloze>();
    }
}

你会遇到这样的设计的一个问题是将相关数据加载/使用到生成的完形填空。例如,每种类型(En & Nl)都有相关数据的导航属性。上面的方法并不急于加载它(如果有大量数据在播放,也不应该急于加载)这意味着这些导航属性(NLExpressions/EnExpressions/等)将被保留为#null 或延迟加载。这将是您的设计以及您打算如何使用返回的信息时要警惕的事情。

我个人建议将语言类型的检查外部化,然后转到适当的 NlClozes 或 EnClozes DbSets,以便调用者可以根据需要投影或进一步急切加载相关数据,而不是尝试将此数据作为“完形填空”返回,然后重新返回-当他们需要相关数据时进行转换。

© www.soinside.com 2019 - 2024. All rights reserved.