【问题标题】:Entity Framework Core many to many relation error: Object reference not set to an instance of an objectEntity Framework Core 多对多关系错误:对象引用未设置为对象的实例
【发布时间】:2021-07-10 22:59:06
【问题描述】:

我是 C#/EF Core 的新手,不明白为什么我会收到空​​引用异常:

System.NullReferenceException
HResult=0x80004003
Message=对象引用未设置为对象的实例。
来源=WMS

堆栈跟踪:
在 WMS.Pages.Artikels.Artikel_Verkauf_erfassen.ArtikelVerkaufErfassen.d__33.MoveNext() 在 D:\Project Arbeit\Code\WMS\Pages\Artikels\Artikel Verkauf erfassen\ArtikelVerkaufErfassen.razor.cs:line 44

我有一个多对多的关系并试图获取分支的文章:

void Add()
{
    var availableQuantity = BranchItems.Find(bi => bi.ArticleId == articleSale.ArticleId)
    .BrancheArticles.Find(ba => ba.ArticleId == articleSale.ArticleId).Quantity;
}

类结构如下:

public class ArticleModel
{
    [Key]
    public int ArticleId { get; set; }

    [Required]
    public string ItemNumber { get; set; }

    [Required]
    public string ItemName { get; set; }

    [Required]
    [MaxLength(40)]
    [MinLength(10)]
    public string ArticleDescription { get; set; }

    [Range(50, 10000)]
    [DataType(DataType.Currency)]
    [Column(TypeName = "decimal(18, 2)")]
    public decimal Preis { get; set; }

    [Range(1,100, ErrorMessage = "sollte von 1 bis 100 Stück sein")]
    public int Menge { get; set; }

    public List<BranchArticle> BrancheArticles { get; set; } = new List<BranchArticle>();
}

public class BranchArticle
{
    public int BranchId { get; set; }
   
    public int ArticleId{ get; set; }

    public BranchModel Branch { get; set; } = new BranchModel();

    public ArticleModel Article { get; set; } = new ArticleModel();

    public int Quantity { get; set; }
}

public class BranchModel
{
    [Key]
    public int Id { get; set; }
    public Guid BranchId { get; set; }
    public string BranchCode { get; set; }
    public string BranchName { get; set; }
    public string Street { get; set; }
    public string HouseNr { get; set; }
    public string ZipCode { get; set; }
    public string Location { get; set; }
    public string ContactPerson { get; set; }
    public string TelefoneNr { get; set; }
    public string Email { get; set; }

    public List<BranchArticle> BrancheArticles { get; set; } = new List<BranchArticle>();  
}

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder.Entity<BranchArticle>()
        .HasKey(ab => new { ab.BranchId, ab.ArticleId });

    modelBuilder.Entity<BranchArticle>()
        .HasOne<ArticleModel>(ab => ab.Article)
        .WithMany(am => am.BrancheArticles)
        .HasForeignKey(ab => ab.ArticleId);

    modelBuilder.Entity<BranchArticle>()
        .HasOne<BranchModel>(ab => ab.Branch)
        .WithMany(bm => bm.BrancheArticles)
        .HasForeignKey(ab => ab.BranchId);

    modelBuilder.Entity<BranchArticle>(entity => { entity.ToTable(name: "BranchArticles"); });

    base.OnModelCreating(modelBuilder);
}

【问题讨论】:

  • 哪一行报错了?
  • *var availableQuantity = BranchItems.Find(bi => bi.ArticleId == articleSale.ArticleId) ----> 给出正确的值
    .BrancheArticles.Find(ba => ba.ArticleId == articleSale.ArticleId).Quantity; ----> 抛出错误

标签: c# entity-framework-core


【解决方案1】:

可能其中一个 Find 函数失败了(返回 null)。

我建议你像这样分解你的代码。

var branchItem = BranchItems.Find(bi => bi.ArticleId == articleSale.ArticleId);
if(branchItem == null) {
    // throw an error or print an error message, etc...
} else {
    var article = branchItem.BrancheArticles.Find(ba => ba.ArticleId == articleSale.ArticleId);
    if (article == null) {
        // throw an error or print an error message, etc...
    } else { 
        var quantity = article.Quantity;
    }
}

您可能还考虑使用 Where() + SingleOrDefault() 而不是 Find()。

【讨论】:

  • 感谢您的帮助。问题是我没有在上下文中添加预先加载的逻辑。我错过了“包括”。解决方案是: return await _wmsDBContext.Articles.Where(predicate).Include(a=> a.BrancheArticles).ToListAsync();
  • 这就是为什么我建议您使用 Where() 而不是 Find() 但我不想深入杂草。如果使用 Where(),Linq 会延迟加载缺失的数据。
猜你喜欢
  • 2013-10-13
  • 1970-01-01
  • 1970-01-01
  • 2020-03-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-12-09
  • 1970-01-01
相关资源
最近更新 更多