How can I specify the collation of a column, a table, or a database by using annotation or Fluent API? I know there are some clean ways for MySql Provider. However, I couldn't find any way for SQL Server other than executing a raw SQL command.
UseCollation() for database and column levels was added to EF Core 5.
Looks like it will not be done at all:
Here is the closed Issue in aspnet/EntityFrameworkCore: CodeFirst: Set column collation
We discussed and concluded that setting different collations per column isn't a very common requirement and it's probably not something we would make first class in EF. This would be a good candidate for using annotations to define additional metadata and then extending our SQL generators to process those and specify collation.
The only solution seems to be this one: Entity Framework Code First - Change Table Column Collation
... you can create custom database initializer and execute ALTER TABLE command.
Although it is possible to change the collation of the database after creation (while there are some data in its tables), it is better to set the collation of the database before creating any tables.
So in EF core for creating database initially before creating any table:
It is better to make sure you have not added any DbSet in the DbContext file of your project.
Open the Nuget Package Manager
Run this code
PM> add-migration CreateDatabase
Right now an empty Up and Down method is created in a migration file like this:
protected override void Up(MigrationBuilder migrationBuilder)
{
}
protected override void Down(MigrationBuilder migrationBuilder)
{
}
Write this code in the Up method. Make sure your collation Name is correct.
migrationBuilder.AlterDatabase("CollationName");
//or
migrationBuilder.Sql("EXEC('ALTER DATABASE [POMADB] COLLATE CollationName ');", suppressTransaction: true);
Run this code
PM> update-database
I have tested this code in .NET Core 5, Visual Studio 2019, Ef core 5.0.9
For further information look at this link Ability to specify database collation
Related
I've always used the edmx file approach and just run "update from database". Now i am using Code first from existing database.
When the DBA changes the database schema, how do I update my dbcontext file and POCOs to match? Is that what migrations are for? Do I just delete everything int he models folder and re-create?
"Code-First" has two different meanings in EF. It's both a Modeling workflow and a Mapping style. You can do Code-First Mapping with Database-First Modeling. You simply regenerate your entity types after changing the database, or change them manually to match the database change. This is what's called "Code-First From and Existing Database"
I have an MVC web application with code-first Entity Framework. We install this application in various computers as a local application. I made a migration to upgrade the database (in this case I added a new table), and after running the migration on upgrade, I want to insert initial data to the database so the users will be able to add/edit/delete them but I don't want the table to be empty at the first time.
Is there a way to do it automatically on upgrade without running a SQL script manually?
Migration class has up method,you can override it and insert/update records using SQL :
public override void Up() {
AddColumn("dbo.Posts", "Abstract", c => c.String());
Sql("UPDATE dbo.Posts SET Abstract = LEFT(Content, 100) WHERE Abstract IS NULL");
}
(Source)
Yes there is. You essentially write a class to conditionally check and insert values, and then you link this class to your entity framework database initialiser. It runs each time there is a migration to be performed, but I think you can change exactly when it runs (e.g. Application startup).
This link will give you the rough idea:
Entity Framework Inserting Initial Data On Rebuild
I have an exact code sample on my PC but I won't be on it until tomorrow. If this link doesn't quite do what you want, I can send you some code tomorrow which definitely will.
We are using Entity Framework 4 RC on Visual Studio 2010 with DB2 version 9.7.3.4. I also have the VS Add-ins and can see the DB2 database in Server Explorer. I have created a very simple VS console project and it works fine against SQL Server, so I know it is valid. I have references to "IBM.Data.DB2.9.7.3" and "IBM.Data.DB2.Entity" in my project.
In app.config my connnection string is:
<add name="ProductContext"
providerName="IBM.Data.DB2"
connectionString="Database=DB2TEST;User ID=XXXX;PWD=XXXX;Server=XXXX;Persist Security Info=True;"/>
The first statement in my code is a database initializer:
DbDatabase.SetInitializer<ProductContext>(new DropCreateDatabaseIfModelChanges<ProductContext>());
During run-time when I reach a line that causes a change to the data context I get the error:
Model compatibility cannot be checked
because the database does not contain
model metadata.
Since I requested that the database be dropped, this does not seem to be a logical error. Does anyone know what the cause could be?
I would try to inherit from CreateDatabaseIfNotExists first, which will add the EdmMetadata table to the schema. I believe the error is that EF is saying that it cannot find that table.
So
DbDatabase.SetInitializer<ProductContext>(new CreateDatabaseIfNotExists<ProductContext>());
Run it once, then change to DropCreateDatabaseIfModelChanges once the EdmMetadata table exists.
Try removing the IncludeMetadataConvention like this:modelBuilder.Conventions.Remove<System.Data.Entity.Infrastructure.IncludeMetadataConvention>();
To avoid the "dbo" issue, just map all your entities using either DataAnnotation attributes or Fluent mapping:
[Table("Product", SchemaName = "MySchema")]
public class Category { //DataAnnotoaion approach
modelBuilder.Entity<Category>().ToTable("Categories", "MySchema"); //Fluent approach
With CTP4, I used to be able to do the following (as suggested by ptrandem):
modelBuilder.IncludeMetadataInDatabase = false
With this line of code, EF doesn't create the EdmMetadata table in my database, and doesn't track model changes.
I was unable to find a way to accomplish this in the new CTP5, so now every time I change my model, I get this:
The model backing the 'MyContext'
context has changed since the database
was created. Either manually
delete/update the database, or call
Database.SetInitializer with an
IDatabaseInitializer instance. For
example, the
DropCreateDatabaseIfModelChanges
strategy will automatically delete and
recreate the database, and optionally
seed it with new data.
So, does everybody know where is the IncludeMetadataInDatabase property in CTP5? Thanks.
CTP5 includes a very cool feature called Pluggable Conventions that can be used to Add/Remove conventions. IncludeMetadataInDatabase has been removed and being replaced with a
pluggable convention that does the same thing for you:
modelBuilder.Conventions
.Remove<System.Data.Entity.Database.IncludeMetadataConvention>();
The equivalent in CTP5 to switch off initializer logic: In your Application_Start in Global.asax, enter the following:
System.Data.Entity.Database.DbDatabase.SetInitializer<MyDBContext>(null);
In EF 4.1
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Conventions.Remove<IncludeMetadataConvention>();
}
Have been looking for this all over, and I had to find the answer right after posting my question, DUH. Right from the ADO.NET team blog:
In CTP5 we have removed the need to
perform additional configuration when
mapping to an existing database. If
Code First detects that it is pointing
to an existing database schema that it
did not create then it will ‘trust
you’ and attempt to use code first
with the schema. The easiest way to
point Code First to an existing
database is to add a App/Web.config
connection string with the same name
as your derived DbContext (...)
I have a single hosted SQL Server DB and I don't have permissions to drop it. How do I make EF create tables from my domain classes? RecreateDatabaseIfModelChanges and AlwaysRecreateDatabase try to drop DB, CreateDatabaseOnlyIfNotExists doesn't create the tables.
Thx
CreateDatabaseOnlyIfNotExists is the default strategy. It means you don't need to even set it through the Database.SetInitializer. EF Code First will check the database and if couldn't find one with the same name as your context's fully qualified name, it will create one for you.