I’m using SqlServerCompact, Entity framework with code-first and I’m generating the connection string dinamically because the database it’s generated when the user requests it.
I followed suggestions from this question: How do I programmatically set the connection string for Entity-Framework Code-First? however, I still have problems, infact I get an exception complaining that the schema in the model is not the same as used in code.
That’s obvius however, I want the schema to be generated from code, so I really can’t understand why this happen
Can someone help me?Here is the code used:
NerdDinners.cs
class NerdDinners : DbContext
{
public static string CreateConnectionString(string dbPath = @"|DataDirectory|\NerdDinners.sdf")
{
SqlCeConnectionStringBuilder sqlConnection = new SqlCeConnectionStringBuilder();
sqlConnection.Password = "9023fase93";
sqlConnection.DataSource = dbPath;
EntityConnectionStringBuilder connection = new EntityConnectionStringBuilder();
connection.Metadata = @"res://*/NerdDinnersModel.csdl|res://*/NerdDinnersModel.ssdl|res://*/NerdDinnersModel.msl";
connection.Provider = "System.Data.SqlServerCe.3.5";
connection.ProviderConnectionString = sqlConnection.ToString();
return connection.ToString();
}
public NerdDinners() : base() { }
public NerdDinners(string nameOrConnectionString) : base(nameOrConnectionString) { }
public DbSet<Dinner> Dinners { get; set; }
public DbSet<RSVP> RSVPs { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
Database.SetInitializer<NerdDinners>(new NerdDinnersInitializer());
Database.DefaultConnectionFactory = new SqlCeConnectionFactory("System.Data.SqlServerCe");
base.OnModelCreating(modelBuilder);
}
}
Program.cs
class Program
{
static void Main(string[] args)
{
NerdDinners nerdDinner = new NerdDinners(NerdDinners.CreateConnectionString());
Console.WriteLine("Inizio test");
var res = from d in nerdDinner.Dinners
select d;
Console.WriteLine("Dinners:");
foreach (var item in res)
Console.WriteLine(item.ToString());
Console.WriteLine("End");
// Usato per terminazione
Console.ReadKey();
}
}
An this is my solution situation (an image):

EDIT 1:
The error is a MetadataException, it complains about invalid schema
EDIT 2:
NerdDinnersInitializer.cs
class NerdDinnersInitializer : DropCreateDatabaseAlways<NerdDinners>
{
public NerdDinnersInitializer() : base() { }
protected override void Seed(NerdDinners context)
{
var toadd = new List<Dinner>
{
new Dinner
{
Address = "bla",
DinnerID = 0,
EventDate = DateTime.Parse("2010-12-03"),
HostedBy = "mclink",
Title = "Notitle",
},
new Dinner
{
Address = "Fiwe",
DinnerID = 0,
EventDate = DateTime.Parse("2011-12-03"),
HostedBy = "ngi",
Title = "Bah",
},
};
toadd.ForEach(item => context.Dinners.Add(item));
context.SaveChanges();
base.Seed(context);
}
}
I found the answer with deep google searching.
I understood that I misunderstood how code first works, infact you can’t create a database you want to connect to if you are using code-first.
I still don’t understand if you can save in a chosen place the database generated with code-first (I think you can’t).
However, if you want to connect to an existing database file you have to use model-first or database-first approach you can’t use code first
This is what I understood, hopefully I’m not wrong.
This question explains it better: Why does Entity Framework Code-First (with an existing DB) keep trying get data from an EdmMetadata table?
EDIT 1:
It looks like I was wrong, is possible, but you need SQL Server compact 4.0 and not 3.5 (I was having problems with it), also you need vs 2010 and entity framework 4.1.
Then, just follow the answer to this question to create dinamically the string: Is possible to create a database (Sql Server compact) on a given path if we use Entity framework with code-first approach?