1

我有一个小型演示应用程序来解决存储在数据库中的二进制数据。请参见下面的相关代码:如何在编辑时保留类型varbinary的图像数据?

实体类:

[HiddenInput(DisplayValue = false)] 
    public int Id { get; set; } 

    [Display(Name = "Full Name:")] 
    public string Name { get; set; } 

    [DataType(DataType.Upload)] 
    [Display(Name = "Photo:")] 
    public byte[] ImageData { get; set; } 

    [HiddenInput(DisplayValue = false)] 
    public string ImageMimeType { get; set; } 

编辑动作:

[HttpGet] 
    public ActionResult Edit(int id) 
    { 
     var mensPlayer = _dataSource.MensPlayers.FirstOrDefault(p => p.Id == id); 

     return View(mensPlayer); 
    } 

    [HttpPost] 
    public ActionResult Edit(MensPlayer mensPlayer, HttpPostedFileBase image) 
    { 
     if (ModelState.IsValid) 
     { 
      //Added line below 
      _dataSource.ImageTemp(mensPlayerInDb, mensPlayer); 
      if (image != null) 
      { 
       mensPlayer.ImageMimeType = image.ContentType; 
       mensPlayer.ImageData = new byte[image.ContentLength]; 
       image.InputStream.Read(mensPlayer.ImageData, 0, image.ContentLength); 
      } 
       //Added line below 
      mensPlayer.ImageData = mensPlayerInDb.ImageData; 

      //Save Player 
      _dataSource.Update(mensPlayer); 
      _dataSource.Save(); 
      TempData["message"] = string.Format("{0} has been saved", mensPlayer.Name); 
      return RedirectToAction("Detail", "MensPlayer", new {id = mensPlayer.Id}); 
     } 
     return View(mensPlayer); 
    } 

的getImage方法:

public FileContentResult GetImage(int id) 
    { 
     var image = _dataSource.MensPlayers.FirstOrDefault(p => p.Id == id); 
     if (image != null) 
     { 
      return File(image.ImageData, image.ImageMimeType); 
     } 
     return null; 
    } 

显示图片:

@if (Model.ImageData != null) { 
    <div > 
     <img width="300" height="400" src="@Url.Action("GetImage", "MensPlayer", 
             new { Model.Id })" alt="Player Image"/> 
    </div> 
} 

DataSource类

public interface IDataSource 
{ 
    IQueryable<MensTeam> MensTeams { get; } 
    IQueryable<MensPlayer> MensPlayers { get; } 
    IQueryable<MensHome> MensHomes { get; } 
    void Save(); 
    void Update(MensPlayer mensPlayer); 
    void Delete(); 
    void ImageTemp(MensPlayer mensPlayerInDb, MensPlayer mensPlayer);//I added this 
} 

在DB类

void IDataSource.Save() 
    { 
     SaveChanges(); 
    } 

    void IDataSource.Update(MensPlayer mensPlayer) 
    { 
     Entry(mensPlayer).State = EntityState.Modified; 
    } 
    //Added code below 
    void IDataSource.ImageTemp(MensPlayer mensPlayerInDb, MensPlayer mensPlayer) 
    { 
     Entry(mensPlayerInDb).CurrentValues.SetValues(mensPlayer); 
    } 

我的问题是,每次我尝试编辑球员的时候,每一个数据很好地从数据库中检索出来,但是当我编辑保存后,ImageData丢失了,更像是重放用空值来存储原始数据。就像,应用程序希望我在每次编辑尝试时重新上传图像。

我能做些什么来清理它?

回答

0

那么,如果imagenull那么在您的实体mensPlayer.ImageDatanull。稍后当您拨打_dataSource.Update(mensPlayer)时,您将实体状态设置为Modified(至少我猜Update只是将状态设置为Modified),因此您告诉EF您也修改了图像(即将其设置为null)和EF将保存这一变化。

为了解决这个问题,您可以加载包括从数据库中第一个图像的实体...

var mensPlayerInDb = context.MensPlayers.Find(mensPlayer.Id); 
mensPlayer.ImageData = mensPlayerInDb.ImageData; // save the ImageData 
// copy changed values to loaded entity and save it, ImageData is unchanged 
context.Entry(mensPlayerInDb).CurrentValues.SetValues(mensPlayer); 
context.SaveChanges(); 

...或者你可以尝试:

context.Entry(mensPlayer).State = EntityState.Modified; 
context.Entry(mensPlayer).Property(m => m.ImageData).IsModified = false; 

后者方法不适用于EF < 5.0(因为一旦实体被标记为Modified,禁止将属性的Modified状态设置为false),但它应该与EF 5一起使用。

您需要将其中一种解决方案集成到您的_dataSource服务类中,可能是通过引入新方法,因为它不适用于您的常规方法Update

+0

对不起,我在生活中有一些东西,但我又回来了。第二个选项看起来很容易实现,但会在第一行设置要修改的所有内容时吐出一个错误。在第一个选项中,我明白代码正在归档的内容,但我在实施该解决方案时遇到了麻烦。看到并告知我是否在正确的轨道上。 – Komengem

+0

@KomengeMwandila:但是你并没有在任何地方使用ImageTemp,也没有从数据库中加载原始图像,是吗? – Slauma

+0

我已更新编辑操作。但有一个问题。是这条线neccessay:'var mensPlayerInDb = context.MensPlayers.Find(mensPlayer.Id);'当我有这条线:'var model = _dataSource.MensPlayers.Single(p => p.Id == id );'在我的HttpGet中?我无法在该行代码中使用查找属性?当我生成 – Komengem

相关问题