Entity Framework 4 and DB2: database generation error - entity-framework-4

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

Related

SQL Server Collations In EF Core

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

How to update a database schema in Spring4D 1.2

I'm experimenting with Spring4D 1.2's simple ORM (Marshmallow). I could get it to work pretty well but I can't find out how to have it update an existing database with a new schema.
For instance, in the "GettingStarted" project, I added one property to the data model:
[Entity]
[Table('Products')]
TProduct = class
{...}
[ColumnAttribute('PRODUCTINFO',50)]
property Info: string read fInfo write fInfo;
No matter what, I can't get the framework to update the schema if the database already exists.
What am I missing ? Must I do that manually outside the framework ?
Schema update is currently not supported nor planned from my side.
Generating the necessary drops and recreate would be reasonably easy but that is only part of the story as you probably want to keep any existing data. From using SQL Server Data Tools I know how deep this rabbit hole can go.

Prevent synchronization of identity column when inserting with EntityFramework

Using EF4 /w SQL Server 2008.
The following code (against a table with a PK, defined as Int IDENTITY(1,1):
ctx.AddObject(GetEntitySetName(), newEntity);
ctx.SaveChanges();
The results when profiling SQL are the insert statement following by a lookup against the table I'm inserting into:
SELECT ID FROM Table
WHERE ID = ##ScopeIdentity AND ##RowCount > 0
Is there a way to prevent EntityFramework from retreiving the Identity seed? I don't need the ID back in my .Net code and under high volume situations it seems like a wasted operation.
Altenatively, is there a way to tell EF to change the way it performs this operation? The strategy used goes against recommendations made by Microsoft in this defect report:
http://connect.microsoft.com/SQL/feedback/ViewFeedback.aspx?FeedbackID=328811
You cannot change this behavior when using database generated keys (properties marked with StorgeGeneratedPattern.Identity). EF needs a real key value for inserted entity so the only way to avoid the query is to not using database generated keys at all and handling it yourselves in the application.

Code First and Model First in the same project?

I have two databases that I am accessing. The first is against a contact database which I connected to using EF Model First; creating the edmx. I have since begun to learn the virtue of CODE First when working with Entity Framework, so I decided I would, in the same project, write the Product database using Code First techniques, allowing the database to be generated from the code I am writing.
Everything compiles fine. The problem occurs when I hit my harness and it attempts to create the Product database and retreive a list of values from one of the tables...
I get the folowing error "Could not find the conceptual model type for 'Core.Data.Account'", when I attempt to enumerate the ProductLines property (Line3 below).
1. using (var ctx = new ProductDb())
2. {
3. var lines = ctx.ProductLines.ToList();
4. this.litOne.Text = lines.Count.ToString();
5. }
After some research it appears that this message may be occuring because of multiple entities with the same name (regardless of namespace), however there is nothing in the ProductDb context with the name "Account".
There is a class in the OTHER context created by the Model First approach named "Account". But how/why would that make a difference? They each point to different databases i.e. different connection strings. Why would the ProductDb be attempting to create a table called Account, when it should be completely unaware of it's exstence?
thoughts?
Thank you as always!,
- G
I bumped into the same problem, but the other way around: first a DbContext + generated database and then generated an edmx off the database (just for a little presentation). It appeared to be a restriction in EF: EF currently has a restriction that POCO classes can't be loaded from an assembly that contains classes with the EF attributes.
The only thing you can do for now is keep the contexts in separate assemblies.

Understanding VS's ability to create database on first run

I'm working with a (.net4 / mvc3 ) solution file downloaded (from a reputable source) where a connection string exists in web.config but I don't see explicit instructions to create the database and there's no included '.mdf'. The first time I build I got a runtime error regarding lack of permissions to CREATE database. So I created a blank db and made sure the string referenced a SQL user that had .dbo/owner rights to the db just created.
But subsequent builds don't seem to execute that same initialize db script - where ever that's stored.
Where is this 'first use' convention for creating databases documented?
thx
That is a feature of Entity Framework Code First. I am not sure what you are looking for exactly, but searching for "EF Code First Initialization Strategy" might help.
For instance read this article: EF Code First DB Initialization Using Web.Config
I assume you are talking about Entity Framework, which allows you to create the database from an instance of an ObjectContext object, which is used in any of the three approaches in EF (database-, model- and code-first).
Look for a line that actually calls ObjectContext.CreateDatabase(). If one of the supported ADO.NET provides is used (SQL Server or SQL Server CE 4.0) this will generate the required SQL Statements. Assuming the classic Northwind example, you might find something like that:
NorthwindContext context = new NorthwindContext();
if (!context.DatabaseExists())
{
context.CreateDatabase();
}
If this is in fact a code-first application, "lalibi" is right about the initialization strategy which by default doesn't require you to explicitly create the database. (But my guess is, that it actually uses a statement internally very similar to mine).

Resources