これを試して:
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
データのみを個別にクエリし、必要に応じてバイナリ データを個別に一括読み込みまたは遅延読み込みできます。これら 2 つのエンティティ間のリレーションシップの流暢なマッピングを次に示します。
// 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 の answer と同様の方法でHttpPostedFileBase
プロパティを持つことができます。その後、コントローラー アクションはビューモデルからデータを取得し、それを使用してエンティティにデータを設定できます。Lugar