1

I'm using Visual Studio 2015, SQL Server 2014, EF 6, MVC 5. EF is throwing the following error for me on SaveChanges():

Implicit conversion from data type nvarchar to varbinary(max) is not allowed. Use the CONVERT function to run this query.

I can't figure out what's wrong because I have no varbinary(max) columns; I never have. Why is it trying to convert between the two? In case it matters, I tried switching the columns to varchar but the same problem happens (with varchar in the error instead of nvarchar). How can I fix this problem?

I have migrations turned off by putting this in the MyContext constructor:

Database.SetInitializer<NxContext>(null);

EF context:

public class MyContext : DbContext
{
    public MyContext() : base("MyContext")
    {
        Database.SetInitializer<MyContext>(null);
    }

    public DbSet<Person> Persons { get; set; }

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Configurations.Add(new PersonMap());

        modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
    }
}

Base class:

public class Person
{
    public int Id { get; set; }
    public string Email { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
}

EF mapping. I tried specifying the column types with HasColumnType("nvarchar") but that had no effect. (That's the default for EF anyway, so it should be unnecessary.)

public class PersonMap : EntityTypeConfiguration<Person>
{
    public PersonMap()
    {
        Property(u => u.Email).IsRequired().HasMaxLength(320);
        Property(u => u.FirstName).IsRequired().HasMaxLength(75);
        Property(u => u.LastName).IsRequired().HasMaxLength(75);
    }
}

The simplified method that's updating the DB:

public class PersonService : IPersonService
{
    public void Create()
    {
        using (var db = new MyContext())
        {
            var person = new Person
            {
                Email = "test@example.com",
                FirstName = "TestFN",
                LastName = "TestLN"
            };
            db.Persons.Add(person);
            db.SaveChanges(); // error thrown here
        }
    }
}

DB schema:

DB schema

vaindil
  • 7,536
  • 21
  • 68
  • 127
  • did you refresh your `.edmx` file.. sounds like something in your table schema when you initially created your tables changed.. – MethodMan Jul 11 '16 at 16:44
  • @MethodMan I don't have a `.edmx` file as far as I know.... – vaindil Jul 11 '16 at 16:45
  • Is this code first? If so, can you show your migrations? Is the error thrown upon creation of the context, or upon saving changes? – Jcl Jul 11 '16 at 16:49
  • @Jcl I have migrations disabled using `Database.SetInitializer(null);`. The error is thrown on `SaveChanges()`. – vaindil Jul 11 '16 at 16:50
  • Can you provide the SQL that generates this error? – wablab Jul 11 '16 at 16:52
  • What you show in the question should be no problem then... have you tried putting a simple context with just that `Person` DbSet in a different project? It looks like there's something you are not showing in your question – Jcl Jul 11 '16 at 16:52
  • Btw, having `DbContext.SetInitializer` in your dbcontext's constructor is not a good idea... EF will try to call the initializer -before- it gets to your constructor code... you need to write that before any usage of that context (unless you are talking a *static* constructor... which is a bad idea for other reasons [*coupling the initializer to the context*], but should work) – Jcl Jul 11 '16 at 16:53
  • @Jcl Where is the correct place for it? [This answer](http://stackoverflow.com/a/29394811/1672458), [this tutorial](http://www.entityframeworktutorial.net/code-first/turn-off-database-initialization-in-code-first.aspx), and [this thread](https://social.msdn.microsoft.com/Forums/en-US/a017f59f-b8b9-4aec-b877-b14a74f9e841/ef6-code-first-with-existing-database-disable-migration?forum=adodotnetentityframework) all say to put it in the constructor. I just added the context to the question. – vaindil Jul 11 '16 at 16:56
  • Are there any triggers or check constraints on the table you're writing to? – wablab Jul 11 '16 at 16:59
  • @Vaindil I'd say the first two links just say it wrong. The last link actually uses a *static* constructor (which again, it's bad for other reasons, but does work). Where to put it depends on your application... in my applications, I generally set the initializer on a specific bootstrapper class I use (but you can use the configuration xml, global.asax if web, or just one static class with a method you call on your app's startup... there are plenty of places, but the context's *instance* constructor: nope) – Jcl Jul 11 '16 at 16:59
  • @wablab No, the table is plain and has nothing except those columns in the schema. – vaindil Jul 11 '16 at 17:01
  • @Jcl Okay, I think I understand. I moved it to `Application_Start` in Global.asax. – vaindil Jul 11 '16 at 17:03
  • I made an almost exact replica (added a connection string) of this question and it works just fine. Again: I think your are not showing something that is causing the error (which you may think it's not important): there are some typos in your question too, which is why I think this is heavily edited (`Firstname` in the class vs `FirstName` everywhere else, etc.). Unless you have a reproduceable example, there's no way we can help you here. – Jcl Jul 11 '16 at 17:19
  • @Jcl You're correct, I did edit it for simplicity. I just edited my code and DB to be _exactly_ as in the question, no differences whatsoever. The error is now that I can't insert NULL into a specific column, but that column/property no longer exists in the class, mapping, service, DB, anywhere. – vaindil Jul 11 '16 at 17:32
  • That definitely doesn't sound like right... are you 100% sure you are connecting to the right database? Can you check `Database.Connection.ConnectionString` on your context's constructor and see if that looks right? – Jcl Jul 11 '16 at 17:34
  • @Jcl Yes, I verified that. I have a remote dev DB and my local DB. I deleted the remote DB entirely and renamed my local one, then updated the connection string with the new unique name. Problem is still happening. – vaindil Jul 11 '16 at 17:35
  • 1
    @Vaindil I mean just make sure that your context is actually using the connection string you think it's using (i.e., check it on a instance of the actual context) – Jcl Jul 11 '16 at 17:36
  • @Jcl You're a genius, I didn't think to check that. It's using LocalDB, but I don't know how it's even finding that because I don't have it configured anywhere. – vaindil Jul 11 '16 at 17:37
  • @Vaindil if you pass a name to the dbcontext's base constructor, it either uses a named connection string with that name, or if it doesn't find any, it uses `(localdb)` with that database name (in your case: `public MyContext() : base("MyContext")` would use a `(localdb)` database named `MyContext` unless you have a named connection string called `MyContext`) – Jcl Jul 11 '16 at 17:38
  • @Jcl Okay, I'll have to figure this out because I definitely have it declared with the correct name in Web.config. If you want to post this as the answer I'll gladly accept it. – vaindil Jul 11 '16 at 17:39

1 Answers1

1

After some debate on the comments, it seems the problem was that the context was not getting the right connection string, and it was using a different database on (localdb), thus the strange errors.

Jcl
  • 27,696
  • 5
  • 61
  • 92