【问题标题】:MVC4 Code First Entity Framework Upload large files to a SQL Server databaseMVC4 Code First Entity Framework 将大文件上传到 SQL Server 数据库
【发布时间】:2014-01-04 08:04:09
【问题描述】:

当我尝试将文件保存到我的 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);

感谢任何和所有的帮助。

【问题讨论】:

  • 为什么要使用存储过程将数据插入到已经映射到 EF 的表中?
  • 你知道没有存储过程的方法吗?如果可能并且更简单,我很乐意在没有存储过程的情况下这样做
  • 为什么要在数据库中放置大文件?

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


【解决方案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();
}

【讨论】:

  • 当我这样做时,我得到一个新错误:必须声明标量变量“@FileName”。有什么想法吗?
  • 您需要从存储过程中取消映射该实体的创建。让 EF 在没有存储过程的情况下处理它。
  • 如果我不使用 ExecuteSqlCommand 方法,你会推荐哪种方法?
  • 现在我在这一行得到一个新的编译时错误:dataContext.Entry(entity).State = EntityState.Added;错误状态:无法将类型“System.Data.EntityState”隐式转换为“System.Data.Entity.EntityState”。存在显式转换(您是否缺少演员表?)
  • 我假设您的意思是 dataContext 而不是 dbContext。我试过 dataContext.Create(entity) 但 Create 不是 dataContxt 对象的一部分。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-04-03
相关资源
最近更新 更多