I have data in a SQLite Database. But I can not be sure that it will always be there. So when I start my Program I first want to check if the SQLite Database exists and when not I want to create one with the DbSet's I already have in my DbContext.
public class MaintenanceDB : DbContext
{
public MaintenanceDB() : base (new SQLiteConnection(new
SQLiteConnectionStringBuilder { DataSource = "data.sqlite"}.ConnectionString), true)
{
}
public DbSet<MaintenanceEntry> MaintenanceEntries { get; set; }
public DbSet<ModuleEntry> ModuleEntries { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<MaintenanceEntry>().ToTable("some Table");
modelBuilder.Entity<ModuleEntry>().ToTable("some Table");
}
}
When I delete my SQLite Database and startup my Program again then I want my SQLite Database to be created.
<connectionStrings>
<add name="MaintenanceDB" connectionString="" providerName="System.Data.SqLite" />
</connectionStrings>
public class MaintenanceDB : DbContext
{
public MaintenanceDB() : base ("Name=MaintenanceDB")
And try the solutions below:
var context = new MaintenanceDB();
if (!context.Database.Exists())
context.Database.Create();
Or
var context = new MaintenanceDB();
context.Database.CreateIfNotExists();
Or create an initializer class as below:
// public class ContentInitializer: DropCreateDatabaseAlways <MaintenanceDB>
// public class ContentInitializer: CreateDatabaseIfNotExists <MaintenanceDB>
public class ContentInitializer: DropCreateDatabaseIfModelChanges <MaintenanceDB>
And put this at the beginning of the application.
Database.SetInitializer (new ContentInitializer ());
Related
I use code-first approach and have used SQL Server as database. All the entities are configured like below:
public interface IBaseEntityTypeConfiguration<T>
{
public void Map(EntityTypeBuilder<T> builder);
}
// My entity
public class Student : IBaseEntityTypeConfiguration<Student>
{
public Id { get; set; }
public string Name { get; set; }
public void Map(EntityTypeBuilder<Student> builder)
{
// Configure entity
}
}
In the ApplicationDbContext all the classes which are inherited from IBaseEntityTypeConfiguration are added to the modelBuilder.Configurations.
But I came up with a new requirement. We should switch from SQL Server to PostgreSql!
I don't want to change the Map() method in all entities, but I want to add some kind of provider which says to modelBuilder that use configurations for SQL Server configurations or PostgreSql configs.
Something like below:
public class ApplicationContext : DbContext
{
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
// var entities = new MsSqlEntityConfiguration().GetAllTypes();
var entities = new PostgreEntityConfiguration().GetAllTypes();
foreach(entity in entities)
modelBuilder.Configuration.Add(entity); // As an example
}
}
Is there any solution that exists as described?
I try to run a CodeFirst example for Entity Framwork with SQLite.
The NuGet Package SQLite.CodeFirst is installed and runs without errors
but it doesn´t create a SQLite DB.
This is my code:
using SQLite.CodeFirst;
using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Text;
namespace EF6SqliteExample
{
class Person
{
public int Id { get; set; }
public string Name { get; set; }
}
class MyContext : DbContext
{
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
var model = modelBuilder.Build(Database.Connection);
ISqlGenerator sqlGenerator = new SqliteSqlGenerator();
string sql = sqlGenerator.Generate(model.StoreModel);
}
public DbSet<Person> Persons { get; set; }
}
class Program
{
static void Main(string[] args)
{
using (var db = new MyContext())
{
var person = new Person() { Name = "John" };
db.Persons.Add(person);
db.SaveChanges();
}
}
}
}
The Connection-String is:
<connectionStrings>
<add name="MyDB" connectionString="data source=.\MyDB.sqlite" providerName="System.Data.SQLite" />
</connectionStrings>
The DbContext class has a method called .Migrate() which will go through the migrations pipeline and create your database if it does not already exist.
Here's a source: Entity Framework Migrations
What I pointed out in your code is, constructor of class MyContext is missing in your code. Add contructor with base and try again.
public MyContext() : base("MyDB")
{
}
after adding constructor in your class, if the Migrations folder is not available yet in your project, you have to write some command as below:
In your visual studio, go to view -> other windows -> package manager console
To enable migration, run enable-migrations . After executing it, you will find Migrations folder.
now add migration with message for current project, run add-migration InitialCreate
to update Database, run update-database
Refresh/Reconnect you server/db. You will find the db there.
Hi I have server with some databases that have the same schema. I use EF6 Database/Model First code and I do not want to create deterrent DbContext for them. for example my generated DbContext is :
public partial class TEST_Rev5_FINALEntities : DbContext
{
public TEST_Rev5_FINALEntities()
: base("name=TEST_Rev5_FINALEntities")
{
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
throw new UnintentionalCodeFirstException();
}
public virtual DbSet<Header> tbl_Headers { get; set; }
public virtual DbSet<Output> tbl_Output { get; set; }
public virtual DbSet<Run> tbl_Run { get; set; }
}
and I created a partial class to set the connection string
public partial class TEST_Rev5_FINALEntities : DbContext
{
public TEST_Rev5_FINALEntities(DbConnection dbConnection)
: base(dbConnection, true)
{
}
}
And I have the following method to create the connection with deterrent connection string:
public DbConnection GetConnectionString()
{
DbConnection conn;
SqlConnectionStringBuilder sqlConnectionStringBuilder = new SqlConnectionStringBuilder
{
DataSource = DataSource,
IntegratedSecurity = false,
UserID = User,
Password = Password,
MultipleActiveResultSets = true
};
SqlConnectionFactory sqlConnectionFactory = new SqlConnectionFactory(sqlConnectionStringBuilder.ConnectionString);
conn = sqlConnectionFactory.CreateConnection(DatabaseName);
return conn;
}
Finally I try to run it like this:
using (var context = new TEST_Rev5_FINALEntities(_dal.Connector.GetConnectionString()))
{
return context.tbl_Headers.FirstOrDefault();
}
but I get this error :
System.Data.Entity.Infrastructure.UnintentionalCodeFirstException
HResult=0x80131509 Message=The context is being used in Code First
mode with code that was generated from an EDMX file for either
Database First or Model First development.
How can I do it?
The behavior EF uses depends on the way your connection string looks. If it includes a metadata attribute like this:
metadata=res://*/model.csdl|res://*/model.ssdl|res://*/model.msl;
It will presume you are using Database or Model first development.
To make sure Code First is used, remove metadata part of the connection string.
I am getting the error The entity type RelyingParty is not part of the model for the current context even though it exists.
My edmx name is SSO. The edmx is present within Entities folder in Entrada.DAL assembly. Following is the code of SSO.Context class
namespace Entrada.DAL.Entities
{
using System;
using System.Data.Entity;
using System.Data.Entity.Infrastructure;
public partial class SSOEntities : DbContext
{
public SSOEntities()
: base("name=SSOEntities")
{
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
throw new UnintentionalCodeFirstException();
}
public virtual DbSet<KeyValuePair> KeyValuePairs { get; set; }
public virtual DbSet<RelyingParty> RelyingParties { get; set; }
}
Following is the connections string in web.config
<add name="SSOEntities" connectionString="metadata=res://*/Entities.SSO.csdl|res://*/Entities.SSO.ssdl|res://*/Entities.SSO.msl;provider=System.Data.SqlClient;provider connection string="data source=dbname;initial catalog=SSO;persist security info=True;user id=user;password=******;MultipleActiveResultSets=True;App=EntityFramework"" providerName="System.Data.EntityClient" />
This is the code where the error is thrown:
public List<RelyingPartyDALDTO> GetAllRelyingParty()
{
List<RelyingParty> relyingPartDB = DBContext.RelyingParties.ToList();
List<RelyingPartyDALDTO> relyingPartyList = RelyingPartyEntityToDAL.Map<List<RelyingPartyDALDTO>>(relyingPartDB);
return relyingPartyList;
}
DBContext is:
public SSOEntities DBContext
{
get
{
if (SSOEntities == null)
{
SSOEntities = new SSOEntities();
}
return SSOEntities;
}
}
I am getting error on executing the statement:
List relyingPartDB = DBContext.RelyingParties.ToList();
Check the error here
Can you see the error in DBContext? Already existing table(KeyValuePair) does not throw any error but the newly added table RelyingParty throws that error.
I am not understanding what is the problem. For any new table i add to edmx, i am facing this issue.
Can anyone please help me?
Try this in your SSOEntities class
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<RelyingParty>().ToTable("RelyingParty");
}
TLDR: Why is Entity Framework appending extra path to the end of my datasource? What do I need to do in order to use this framework? Is there another way to handle this?
I am writing a basic SQL Server CE winforms program to store some data. I originally had 1 context to be used to interact with 1 class. Now, I wish to add another class, and so I refactored out a base context that the original context could be derived from. I have the code running, although I can't create any database with it.
I take a path in from the user to the database and set the |DataDirectory|, which I use for the data source.
<add name="MonsterContext"
connectionString="Data Source=|DataDirectory|; Persist Security Info=False"
providerName="System.Data.SqlServerCe.4.0" />
I intend for the data source to look like
C:Path\To\DatabaseFile.sdf
but it comes out as
C:\Path\To\DatabaseFile.sdf\Namespace.BaseContext`1[Namespace.ModelClass].sdf ]"}
I think this path demonstrates that it is building its own source based on EF defaults.
My base Context is:
public class EntityContext<T> : DbContext where T : class
{
public string TableName { get; set; }
public EntityContext()
: base("name=MonsterContext")
{
}
public EntityContext(string tableName)
{
this.TableName = tableName;
}
public DbSet<T> Entities { get; set; }
}
And My Derived Context is:
public class MonsterReader : Reader<Monster>
{
private List<Monster> monsters;
public List<Monster> Monsters
{
get
{
if (monsters == null)
{
monsters = ReadAll();
}
return monsters;
}
private set { monsters = value; }
}
public MonsterReader(string file)
: base(file)
{ }
public MonsterReader(Stream reader)
: base(reader)
{ }
public void CreateMonsterDatabase(IEnumerable<Monster> monsters)
{
CreateDatabase(monsters, TableName);
}
private string TableName { get; set; }
}
In this problem, it was a simple omission from the base context.
In the Base Entity Context, the first constructor is:
public EntityContext()
: base("name=MonsterContext")
{
}
However, the constructor that takes a table name is
public EntityContext(string tableName)
{
this.TableName = tableName;
}
which is missing the : base("name=MonsterContext")
This call is necessary if you want to call a specific connection string from the app.config.
In this case, the connection string you want to call is "Monster Context". Without specifying which context, Entity Framework defaults using SQL Server CE to
|DataDirectory|\Namespace.NameofContext.sdf