2

I get the following error when I try to save a file to my SQL Server database: No mapping exists from object type System.Data.Linq.Binary to a known managed provider native type.

Here is my Database table:

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

Here is my stored procedure:

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 

Here is my CodeFirst class:

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; }
}

Here is my 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; }
}

here is my code:

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);

Any and all help is appreciated.

3
  • Why are using a stored procedure to insert data into a table that is already mapped to EF? Commented Dec 16, 2013 at 19:35
  • Do you know of a way to do this without a stored procedure? I would be happy to do this without a stored procedrue if that is possible and simpler Commented Dec 16, 2013 at 20:00
  • 1
    Why on earth putting large files in your database? Commented Dec 16, 2013 at 20:19

1 Answer 1

1

Your problem is here:

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

Just store the raw byte array in your entity property, and it should work.

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();
}
Sign up to request clarification or add additional context in comments.

6 Comments

When I do that I get a new error: Must declare the scalar variable "@FileName". Any ideas?
You need to unmap the creation of this entity from a stored procedure. Just let EF handle it without sprocs.
If I don't use the ExecuteSqlCommand method, which method would you suggest?
Now I get a new compile time error on this line: dataContext.Entry(entity).State = EntityState.Added; The error states: Cannot implicitly convert type 'System.Data.EntityState' to 'System.Data.Entity.EntityState'. An explicit conversion exists (are you missing a cast?)
I assume you mean dataContext and not dbContext. I tried dataContext.Create(entity) but Create is not a part of the dataContxt object.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.