How can I define a stored procedure in Entity Framework (code first)? - entity-framework

I define my model in Entity Framework (code first), but how can I define a stored procedure in my model? I want to create my model and have it generate the stored procedure in my database when my database is generated from my model.

Description
There is no built in direct mapping support for stored procedures in Entity Framework code first at the moment. But you can exec any sql query (create your stored procedure) like in my sample.
Sample
public class MyDatabaseContext : DbContext
{
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
DbCommand cmd = Database.Connection.CreateCommand();
cmd.CommandText = "create stored procedure ....";
cmd.ExecuteNonQuery();
}
}
More Information
MSDN - DbCommand Class

I'm using Entity Framework 6 so things may have changed. The database is not created in OnModelCreating, but it did work in the DbInitializer like this...
public class MyDbInitializer : DropCreateDatabaseIfModelChanges<MyDbContext> {
protected override void Seed(MyDbContext context) {
string sql = #"CREATE PROCEDURE...";
context.Database.ExecuteSqlCommand(sql);
base.Seed(context);
}
}

Related

Connection string for code first mode with mysql

I am working on a project that gets connection strings for Entity Framework from environment variables, like this:
public class SomeTests {
[Fact]
public async void TestSomething() {
string connectionString = Environment.GetEnvironmentVariable("APP_CONN_STR");
var appContextOptionsBuilder = new DbContextOptionsBuilder<AppDataContext>();
appContextOptionsBuilder.UseMySql(connectionString); // hardcoded mysql
AppDataContext context = new AppDataContext(appContextOptionsBuilder.Options);
Assert.Equal(context.Country.Count(), 0);
}
}
....
public partial class AppDataContext : DbContext, IAppDataContext
{
public AppDataContext(DbContextOptions options) : base(options)
{
}
public virtual DbSet<Country> Country { get; set; }
...
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<Country>(entity =>
{
entity.ToTable("country");
...
});
...
}
}
The code above is a bootstrapper code for some automated integration testing. Historically every developer is using the same old database instance on the network without a problem. I am trying to make these tests run in an isolated environment, so I have set up an empty new mysql database (using docker to make it reproducible), and let Entity Framework to populate it with a schema.
The problem is, when I create an empty database in this mysql instance and give a connection string to that database, then I am getting table not found errors:
connection str: Server=127.0.0.1;Port=3306;Database=app_mysql_db;Uid=root;Pwd=****;
error: MySql.Data.MySqlClient.MySqlException : Table 'app_mysql_db.country' doesn't exist
I found out that EF will not create tables in existing databases, it will only populate a database with tables if EF itself created it. This is the default behavior of EF.
So I tried to remove the database name from the connection string:
connection str: Server=127.0.0.1;Port=3306;Uid=root;Pwd=****;
error: MySql.Data.MySqlClient.MySqlException : No database selected
So how do I let Entity Framework in Code First mode to create my tables?

Entity Framework 7 Core emulate not supported migration operation

I want use user EF 7 + migration + SQLite. But not all operation is supported.
Can I perform not supported operation manually?
Sample I want remove column.
I add new migration with migrationBuilder.DropColumn (SQLite not support DropColumn)
Can I write code for apply migration with skip DropColumn or run my sql instead of
Solution for SQLite with skip DropColumn
public class DB: DbContext
{
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.ReplaceService<SqliteMigrationsSqlGenerator, SqliteMigrationsSqlGeneratorExt>();
}
}
public class SqliteMigrationsSqlGeneratorExt: SqliteMigrationsSqlGenerator
{
public override IReadOnlyList<MigrationCommand> Generate(IReadOnlyList<MigrationOperation> operations, IModel model = null)
{
//Remover DropColumn from operations
return operations;
}
}

EF5 : Manual table mapping

How to do manual table mapping in Entity Framework 5 using the Code First approach?
What I mean by table mapping is to associate a table name from the database to an entity class with a different name.
This is pretty simple.
[Table("Foo")]
public class Bar {
// properties
}
For fluent api:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<MyEntity>().ToTable("MyTargetTable");
}

Model compatibility exception in Entity Framework

When I execute my web app and try to save data into databse, this exception happens :
Model compatibility cannot be checked because the database does not
contain model metadata. Model compatibility can only be checked for
databases created using Code First or Code First Migrations.
I try lot of issue for resolve this problem , but it persist yet !!
Using migrations isn't really necessary if you're developing on your local machine. You can just set the database Initializer to drop the database always, run some code that interacts with the database, and then you'll see that the database will be recreated and the error will be gone.
Should work, that's how I do it.
delete the database manually, then restart the project with:
public class DbDataContext : DbContext
{
public IDbSet<FlightType> FlightTypes { get; set; }
public DbDataContext()
{
//Validates if database Exists or if is CompatibleWithModel
//Using when Databes is productive - use code first migrations for db changes in this case
//Database.SetInitializer(new ValidateDatabase<DbDataContext>());
//Custom Initializer - crates databse with required entries
//Using while developing
Database.SetInitializer<DbDataContext>(new DatabaseInitializer<DbDataContext>());
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
}
}
DatabaseInitializer:
public class DatabaseInitializer<T> : DropCreateDatabaseIfModelChanges<DbDataContext>
{
protected override void Seed(DbDataContext dbDataContext)
{
dbDataContext.FlightTypes.Add(new FlightType { FlightTypeNummer = "axd", Name = "AXD_LX", IsDefault = true });
base.Seed(dbDataContext);
}
}
ValidateDatabase:
public class ValidateDatabase<TContext> : IDatabaseInitializer<TContext> where TContext : DbContext
{
public void InitializeDatabase(TContext context)
{
if (!context.Database.Exists())
{
throw new InvalidOperationException("Database does not exist");
}
if (!context.Database.CompatibleWithModel(true))
{
throw new InvalidOperationException("The database is not compatible with the entity model.");
}
}
}
Are you trying to use Code-First Migrations? If so, have you run the following command in the Package Manager Console?
PM> Enable-Migrations

How do I map an Entity Framework Code-First model to a single SQL Server Schema?

I am creating an Entity Framework Code-First model to execute ad-hoc queries against a SQL Server database. I am not including any tables/views from the "dbo" schema in my EF model; instead I am only including tables/views from the "model" schema in my database. I do have duplicate names of objects in my database that are separated only by schema (e.g. "dbo.Child" and "model.Child").
Is there one line I can specify in the DbContext that will say in essence "map all entities in this context to the 'model' schema"? I know that I can map each entity to the proper schema (see below), but I'd like to avoid listing out every entity in my database again.
This is what I know I can do:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Child>().ToTable("Child", "model");
modelBuilder.Entity<Referral>().ToTable("Referral", "model");
// 100 lines later...
modelBuilder.Entity<Exit>().ToTable("Exit", "model");
}
This is what I'd like to do:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Conventions.Add(new MapAllEntitiesToSchemaConvention("model"));
}
I couldn't find anyway to do this out of the box in EF 4.2, but I needed all my entities to be in a different schema so I hacked this up in an attempt to keep things DRYer. It uses the same underlying pluralization engine as EF, and the overrides are there incase entities need to specify the table name.
A reference to System.Data.Entity.Design is needed.
public class BaseConfiguration<TEntityType> : EntityTypeConfiguration<TEntityType> where TEntityType : class
{
private readonly static PluralizationService ps = PluralizationService.CreateService(new CultureInfo("en-US"));
public BaseConfiguration() : this(ps.Pluralize(typeof(TEntityType).Name)) { }
public BaseConfiguration(string tableName) : this(tableName, MyContext.Schema) { }
public BaseConfiguration(string tableName, string schemaName)
{
ToTable(tableName, schemaName);
}
}
I define the schema name via a constant string in MyContext, ie:
public class MyContext : DbContext
{
public const string Schema = "my";
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Configurations.Add(new SnapshotConfiguration());
}
}
And my entities configurations look like:
public class SnapshotConfiguration : BaseConfiguration<Snapshot>
{
...
}
Caveat: I still need configuration's for each entity I want in the correct schema - but the jist of it could be adopted elsewhere.