Entity Framework 4.3.1 failing to create (/open) a

2020-08-26 11:34发布

问题:

I've used EF 4.1 (Code First) in an MVC 3 project a while back, and it was good.

Today I tried using EF 4.3.1 (Code First) in a WinForms project and encountered some real voodoo: (The original project I was working on was WinForms, however the same thing is true for the attached Console Application code.)

When trying to enter a simple class into the database, I get the following exception: Cannot open database "Test" requested by the login. The login failed. Login failed for user '[ComputerName]\[Administrator]'.

I've tried checking the SQL Server (2008 R2) configurations but my user does have all the permissions on the server.

NOTE: The Database does not exist when I first run the application.

Even the following sample code does not work :

class Program
{
    public static void Main()
    {
        var person = new Person { Name = "Nathan" };
        using (var db = new MyContext())
        { //#1
            db.Persons.Add(person);
            db.SaveChanges();
        }
        Console.Write("Person saved !");
        Console.ReadLine();
    }
}

public class Person
{
    public int PersonId { get; set; }
    public string Name { get; set; }
}

public class MyContext : DbContext
{
    public DbSet<Person> Persons { get; set; }
    public MyContext()
        : base("Data Source=localhost;Database=Test;Integrated Security=True;")
    { }
}

I've tried re-installing EF 4.3.1 - to no avail. Restarting the SQL-Server also had no effect.

NOTE: I've noticed quite a lot of similar questions around, but none are both the same as mine and answered - here's me hoping I'll get lucky here :)

To clarify: The user being denied access is the Owner (local administrator) of the machine.

EDIT: I've been running a few experiments and I've found something quite strange:

If I pause the program at the line marked "#1" and check the value of db.Database.Exists() via the Watch window, It tells me: "The function evaluation requires all threads to run" with that little wavey button I can click to make it run all threads.

If I click on that button the function evaluates to False.

Now I can do 2 things:

  1. Continue execution: In this case I get the exact same exception.
  2. Execute db.Database.Create() from the Watch window: In this case the program runs successfully to the end and I see the Database, Table and Row created in my SQL Management Studio.

Seems like a simple solution, right? Wrong!

I've tried prefixing the data access with a call to db.Database.CreateIfNotExists(); but then I get the exact same exception on that line.

db.Database.Initialize(true); has no effect either...

NOTE: If by using the above method I create the database, I can use it properly from that point onwards, so that's at least half a consolation :P The problem is, of course, what happens when I add a DropCreateIfModelChanges or DropCreateAlways Initalizer (since I'm in the middle of active development of the model).

Thanks.

[I'm suspecting it's more of a Entity Framework problem than SQL Server.]

回答1:

You can see this exception when debugging if you happen to have "break when exception is thrown" option (Debug->Excptions) turned on. EF is trying to connect to the database but it fails since database does not exist yet so an exception is thrown. You see the exception due to the option above turned on. This exception is actually caught by the Entity Framework and EF will then connect to master database to create the database it was trying to connect in the first step. Once the database is created it will again use the original connection string to talk to the database. So, you can either press F5 to continue debugging since the exception is a first chance exception that will be handled or disable turn off "breaking when exception is thrown" which will result in breaking only for exceptions that are not handled rather than all exception that are thrown.