尝试这个:
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 实体类中。
ContentLength
其他几点注意事项:将,ContentType
和也存储FileName
在您的Foto
实体上可能不是一个坏主意。您可能还想考虑将此实体拆分为 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);
当您使用与上述类似的映射时,数据库中的所有行Foto
和FotoBinary
行都将共享相同的主键 ( Id
)。只要知道一个的Id,就可以用它来查询另一个(Owner
或Content
)的对应行。
最后,我至少会考虑不将Lugar
实体传递到您的 MVC 操作中。您可以改为编写 ViewModel 类,例如LugarViewModel
. 然后,该类可以具有与 Karthik 的答案类似HttpPostedFileBase
的属性。然后,您的控制器操作可以从视图模型中获取数据并使用它来填充实体。Lugar