我如何在Asp.net Mvc4实体框架中使用图像

本文关键字:框架 图像 实体 Mvc4 Asp net | 更新日期: 2023-09-27 18:00:17

在我的类Lugar中,我有这个:

public virtual Foto FotosLugar { get; set; }

我有这样的定义:

public class Foto
{
    [Column(TypeName = "image")]
    public byte[] Binary { get; set; }
}

在我的LugarController中,我尝试过:

 public ActionResult Create(Lugar lugar, HttpPostedFileBase FotosLugar)

我试着做了一些转换,但也没用。。。

我想在类Lugar中存储一个Image。。。。

我如何在Asp.net Mvc4实体框架中使用图像

试试这个:

public ActionResult Create(Lugar lugar, HttpPostedFileBase fotosLugar)
{
    if (fotosLugar != null && fotosLugar.ContentLength > 0)
    {
        var contentLength = fotosLugar.ContentLength;
        var content = new byte[contentLength];
        fotosLugar.InputStream.Read(content, 0, contentLength);
        var foto = new Foto { Binary = content };
        lugar.FotosLugar = foto;
    }
    //... eventually return an ActionResult
}

文件比普通数据更难处理,因为字节包含在Stream对象中。上面的代码从流中读取字节,以便将它们存储在EF实体类中。

还有几个注意事项:在Foto实体上同时存储ContentLengthContentType,可能还有FileName,这可能不是一个坏主意。您可能还想考虑将此实体拆分为2,这样您就可以从原始二进制文件数据中分别查询出文件名、内容类型和内容长度。我们在网站中遇到了一个问题,我们只需要获取文件名,但查询速度很慢,因为由于我们将byte[]列与文件名存储在同一个表上,当我们只需要字符串文件名时,SQL将返回所有二进制数据。最终用类似以下的模型解决:

public class Foto
{
    public int Id { get; set; }
    public int ContentLength { get; set; }
    public string FileName { get; set; }
    public string ContentType { get; set; }
    public virtual FotoBinary Content { get; set; }
}
public class FotoBinary
{
    public int Id { get; set; }
    public virtual Foto Owner { get; set; }
    public byte[] Value { get; set; }
}

这样,您可以只查询string&单独加载int数据,并在需要时单独加载二进制数据。以下是这两个实体之间关系的流畅映射:

// Foto entity
HasRequired(principal => principal.Content)
    .WithRequiredPrincipal(dependent => dependent.Owner)
    .WillCascadeOnDelete(true);
// FotoBinary entity
HasRequired(dependent => dependent.Owner)
    .WithRequiredDependent(principal => principal.Content)
    .WillCascadeOnDelete(true);

当使用类似于上面的映射时,数据库中的所有FotoFotoBinary行都将共享相同的主键(Id)。只要知道其中一个的Id,就可以用它来查询另一个(OwnerContent)的对应行。

最后,我至少考虑不将Lugar实体传递到MVC操作中。相反,您可以编写一个ViewModel类,如LugarViewModel。然后,该类可以具有与Karthik的答案类似的HttpPostedFileBase属性。然后,控制器操作可以从视图模型中获取数据,并使用它来填充Lugar实体。

我不确定这是否与EF有关。看来你还没到那儿。

你的意思是,你不能在控制器中的Create操作中接收文件,对吧?

你至少有两个选择:

  • 使用一个参数(HttpPostedFile/IEnumerable)执行操作,并从模型中单独获取图像
  • 或者您可以简单地访问控制器中的任何位置的Request.Files,您将获得上传文件的集合,然后稍后将其添加到Lugar类中。不需要额外的FotosLugar参数

好吧,这是我对它的看法:

  • 基本实体类应该有一个与最初指定的byte[]属性类似的属性。没关系
  • 定义一个可以传递给视图并可以发布回控制器的视图模型类。这是一个应该具有HttpPostedFileBase类型属性的类。
    • 下面是一个使用POST到传统控制器的教程:(http://haacked.com/archive/2010/07/16/uploading-files-with-aspnetmvc.aspx)
    • 对于API控制器:(https://stackoverflow.com/a/13157581/87454)
  • 将文件获取到控制器后,必须将流转换为字节数组(以便能够将其分配给将存储在SQL Server中的实体对象)。以下是斯基特大师关于如何做到这一点的精彩答案:https://stackoverflow.com/a/221941/87454