C# MVC4代码优先实体框架将大型文件上载到SQL Server数据库
当我尝试将文件保存到SQL Server数据库时,出现以下错误: 不存在从对象类型System.Data.Linq.Binary到已知托管提供程序本机类型的映射 这是我的数据库表:C# MVC4代码优先实体框架将大型文件上载到SQL Server数据库,c#,sql,sql-server,entity-framework,asp.net-mvc-4,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, [FileExten
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
这是我的第一堂课:
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; }
}
公共类FileStreamDbContext:DbContext
{
模型创建时受保护的覆盖无效(DbModelBuilder modelBuilder)
{
基于模型创建(modelBuilder);
配置(modelBuilder.Entity());
}
私有void配置(EntityTypeConfiguration数据文件)
{
datafiles.ToTable(“datafiles”);
属性(a=>a.Id).HasColumnName(“Id”);
属性(a=>a.FileName).HasColumnName(“文件名”).IsOptional();
属性(a=>a.FileData).HasColumnName(“FileData”).IsOptional();
属性(a=>a.FileExtension).HasColumnName(“FileExtension”).IsOptional();
}
公共数据库集数据文件{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);
byte[]fileData=新字节[file.InputStream.Length];
//将文件输入流添加到字节数组中
file.InputStream.Read(fileData,0,Convert.ToInt32(file.InputStream.Length));
//var newFileData=新二进制文件(fileData);
//使用字节数组创建system.data.linq对象
System.Data.Linq.Binary二进制文件=新的System.Data.Linq.Binary(fileData);
使用(var dataContext=new FileStreamDbContext())
{
//数据文件df=null;
//string query=“dbo.sp_InsertFileData,@FileName,@FileData,@FileExtension”;
字符串文件名=Path.GetFileName(file.fileName);
字符串fileExtension=Path.GetExtension(file.FileName);
var filenameparmeter=新的SqlParameter
{
SqlDbType=System.Data.SqlDbType.VarChar,
//DbType=DbType.String,
ParameterName=“FileName”,
值=文件名
};
var fileDataParameter=新的SqlParameter
{
SqlDbType=System.Data.SqlDbType.VarBinary,
//DbType=DbType.Binary,
ParameterName=“FileData”,
值=二进制文件
};
var fileExtensionParameter=新的SqlParameter
{
SqlDbType=System.Data.SqlDbType.VarChar,
//DbType=DbType.String,
ParameterName=“FileExtension”,
值=文件扩展名
};
//var result=dataContext.Database.SqlQuery(“EXEC dbo.sp_InsertFileData@FileName,@FileData,@FileExtension”,
//fileName,newFileData,fileExtension).SingleOrDefault();
//var results=dataContext.Database.SqlQuery(query,filenamepartment,fileDataParameter,fileExtensionParameter);
var results=dataContext.Database.ExecuteSqlCommand(“exec dbo.sp_InsertFileData@FileName,@FileData,@FileExtension”,
文件名、二进制文件、文件扩展名);
非常感谢您的帮助。您的问题在于:
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();
}
为什么要使用存储过程将数据插入到已映射到EF的表中?您知道没有存储过程的方法吗?如果可能的话,我很乐意在没有存储过程的情况下执行此操作,而且非常简单。到底为什么要将大文件放入数据库中?当我这样做时,我会遇到一个新错误:必须声明标量变量启用“@FileName”。有什么想法吗?您需要从存储过程中取消映射此实体的创建。只需让EF在不使用存储过程的情况下处理它。如果我不使用ExecuteSqlCommand方法,您会建议使用哪种方法?现在我在这一行上得到一个新的编译时错误:dataContext.Entry(entity).State=EntityState.Added;错误状态:无法将类型“System.Data.EntityState”隐式转换为“System.Data.Entity.EntityState”。存在显式转换(是否缺少转换?),我假设您指的是dataContext而不是dbContext。我尝试了dataContext.Create(Entity),但Create不是dataContext对象的一部分。