实体框架核心:将上传的文件保存到已连接的表格

时间:2018-06-01 19:59:57

标签: c# entity-framework-core

我有一个与表格相关联的新闻表,我希望保存与新闻相关的图像或pdf。下面是我的模型和Create方法,我将发布的文件保存到连接表中。

但是我收到以下错误。这对我没有意义,因为NewsFiles不应该是我数据库中的对象。 NewsFile是一个表,NewsFiles是虚拟集合。

  

处理请求时数据库操作失败。   DbUpdateException:更新条目时发生错误。看到   细节的内在例外。 SqlException:无效的对象名称   'NewsFiles'。 ApplicationDbContext有待更改的模型更改   在Visual Studio中,使用程序包管理器控制台来构建新的程序包   迁移这些更改并将它们应用于数据库:

     

PM>添加迁移[迁移名称] PM>更新数据库或者,   您可以构建一个新的迁移并从命令提示符处应用它   你的项目目录:

     
    

dotnet ef迁移添加[迁移名称]     dotnet ef数据库更新

  
public class News
{
    [Key] public int Id { get; set; }
    public string Title { get; set; }
    public virtual ICollection<NewsFile> NewsFiles { get; set; }
}

public class File
{
    [Key] public int Id { get; set; }
    public string Filename { get; set; }
    public Byte[] Content { get; set; }
    public virtual ICollection<NewsFile> NewsFiles { get; set; }
}

public class NewsFile
{
    [Key] public int Id { get; set; }
    public int NewsId { get; set; }
    public News News { get; set; }
    public int FileId { get; set; }
    public File File { get; set; }
}

protected override void OnModelCreating(ModelBuilder builder)
{
    base.OnModelCreating(builder);

    builder.Entity<NewsFile>().HasIndex(nf => new { nf.NewsId, nf.FileId });
    builder.Entity<NewsFile>().HasOne(nf => nf.News).WithMany(n => n.NewsFiles).HasForeignKey(nf => nf.NewsId);
    builder.Entity<NewsFile>().HasOne(nf => nf.File).WithMany(c => c.NewsFiles).HasForeignKey(pc => pc.FileId);
}

[HttpPost]
[ValidateAntiForgeryToken]
public async Task<IActionResult> Create(NewsViewModel model)
{
    if (ModelState.IsValid)
    {
        Byte[] file = null;
        using (var ms = new MemoryStream())
        {
            model.File.CopyTo(ms);
            file = ms.ToArray();
        }
        model.News.NewsFiles = new List<NewsFile>()
        {
            new NewsFile()
            {
                File = new Models.File() { Content = file, Filename = model.File.FileName }
            }
        };
        _dbContext.News.Add(model.News);
        await _dbContext.SaveChangesAsync();
        return RedirectToAction("Index");
    }
    return View(model);
}

1 个答案:

答案 0 :(得分:1)

By default

  

EF Core将为上下文类中的所有DbSet属性创建数据库表,其属性与属性相同

因此,您需要覆盖默认约定。我看到你的评论builder.Entity<NewsFile>().ToTable("NewsFile")不起作用。但我只是尝试了它,它解决了这个问题。

当我评论显式映射到表时,我得到了异常SqlException: Invalid object name 'NewsFiles',但它没有提及待处理的模型更改和迁移。因此,您在某种程度上得到了模型和数据库之间的不一致。正如您在评论中所述,重建数据库可以提供帮助