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

相關問題