MVC4 Code First Entity Framework将大型文件上载到SQL Server数据库

时间:2013-12-16 19:30:09

标签: c# sql sql-server entity-framework asp.net-mvc-4

当我尝试将文件保存到SQL Server数据库时出现以下错误: 从对象类型System.Data.Linq.Binary到已知的托管提供程序本机类型不存在映射。

这是我的数据库表:

CREATE TABLE [dbo].[FilesData](
    [Id] [int] IDENTITY(1,1) NOT NULL,
    [FileName] [nvarchar](50) NULL,
    [FileData] [varbinary](max) NULL,
    [FileExtension] [nvarchar](50) NULL,

这是我的存储过程:

ALTER PROCEDURE [dbo].[sp_InsertFileData] 
    @FileName nvarchar(50),
    @FileData varbinary(max),
    @FileExtension nvarchar(50),
    @result nvarchar(1) OUTPUT  
AS
    SET @result = '1'
    INSERT INTO FilesData(FileName, FileData, FileExtension)
    VALUES(@FileName,convert(varbinary(Max),@FileData),@FileExtension) 

    SELECT @result 

这是我的CodeFirst类:

public class DataFile
{       
    [Key]
    public virtual int Id { get; set; }
    public virtual string FileName { get; set; }       
    public virtual byte[] FileData { get; set; }        
    public virtual string FileExtension { get; set; }
}

这是我的dbContect:

public class FileStreamDbContext : DbContext
{
    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        base.OnModelCreating(modelBuilder);
        Configure(modelBuilder.Entity<DataFile>());
    }
    private void Configure(EntityTypeConfiguration<DataFile> datafiles)
    {
        datafiles.ToTable("DataFiles");
        datafiles.Property(a => a.Id).HasColumnName("Id");
        datafiles.Property(a => a.FileName).HasColumnName("FileName").IsOptional();
        datafiles.Property(a => a.FileData).HasColumnName("FileData").IsOptional();
        datafiles.Property(a => a.FileExtension).HasColumnName("FileExtension").IsOptional();
    }


    public DbSet<DataFile> datafiles { get; set; }
}

这是我的代码:

byte[] fileData = new byte[file.InputStream.Length];
//add file input stream into byte array           
file.InputStream.Read(fileData, 0, Convert.ToInt32(file.InputStream.Length));
//var newFileData = new Binary(fileData);
//create system.data.linq object using byte array
System.Data.Linq.Binary binaryFile = new System.Data.Linq.Binary(fileData);
using (var dataContext = new FileStreamDbContext())
{
    //DataFile df = null;
    //string query = "dbo.sp_InsertFileData,@FileName,@FileData, @FileExtension";
    string fileName = Path.GetFileName(file.FileName);
    string fileExtension = Path.GetExtension(file.FileName);
    var fileNameParameter = new SqlParameter 
    { 
        SqlDbType = System.Data.SqlDbType.VarChar,
        //DbType = DbType.String,
        ParameterName = "FileName",
        Value = fileName 
    };
    var fileDataParameter = new SqlParameter 
    {
        SqlDbType = System.Data.SqlDbType.VarBinary,
        //DbType = DbType.Binary,
        ParameterName = "FileData",
        Value = binaryFile 
    };
    var fileExtensionParameter = new SqlParameter 
    {
        SqlDbType = System.Data.SqlDbType.VarChar,
        //DbType = DbType.String,
        ParameterName = "FileExtension",
        Value = fileExtension 
    };
    //var result = dataContext.Database.SqlQuery("EXEC dbo.sp_InsertFileData @FileName, @FileData, @FileExtension",
    //    fileName, newFileData, fileExtension).SingleOrDefault();
    //var results = dataContext.Database.SqlQuery<DataFile>(query, fileNameParameter, fileDataParameter, fileExtensionParameter);
    var results = dataContext.Database.ExecuteSqlCommand("exec dbo.sp_InsertFileData @FileName, @FileData, @FileExtension",
        fileName, binaryFile, fileExtension);

感谢任何和所有帮助。

1 个答案:

答案 0 :(得分:1)

你的问题在这里:

System.Data.Linq.Binary binaryFile = new System.Data.Linq.Binary(fileData);

只需将原始字节数组存储在您的实体属性中,它就可以正常工作。

byte[] fileData = new byte[file.InputStream.Length];
file.InputStream.Read(fileData, 0, Convert.ToInt32(file.InputStream.Length));
using (var dataContext = new FileStreamDbContext())
{
    var entity = new DataFile
    {
        FileName = Path.GetFileName(file.FileName),
        FileExtension = Path.GetExtension(file.FileName),
        FileData = fileData,
    };
    dataContext.Create(entity);
    dataContext.SaveChanges();
}