I have a database with two tables :
Employee Salary
======== ================
Id Name Id EmpId Salary
and of course there is a class for each table to implement code first migration.
Is there any way to copy the database tables from the source database to another database and change the names of the tables using EF code-first?
PS: The target for this method is to create default database with default structure and when new client register create his own tables in existing database with new name
The easiest thing to do is to run code first against the database you are trying to copy the tables from (Add-> New Item -> Data -> ADO.NET Entity Data Model -> Code First from database.) Check off the tables you want to import. When you are done doing that delete the Entity DBContext and the connection string in your web.config. This will create all the models from the db you are trying to create. Add them to your model; Done.
public DbSet<StudentsModel> MyNewTable{ get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder) {
modelBuilder.Entity<MyNewTable>().ToTable("MyTable");
In this case Entity framework layer code will differ from client to client?
Since you will have some more table on one client than another one.
You can change the name by
modelBuilder.Entity().ToTable("mytesttablename"); fluent API
OR table attribute
[Table("mytesttablename")]
public class test
{
}
etc
Related
How do I disable table generation for a specific entity when my DB context is initialized?
public class MyDbContext : DbContext {
public DbSet<MyEntity> MyEntity{ get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder) {
modelBuilder.Ignore<MyEntity>();
base.OnModelCreating(modelBuilder);
}
}
This code helps but it excludes the entity completely and I still need to query it.
Without getting into too much detail, EF compares generated code your DB structure to the previous generated code when looking at migrations: it doesn't actually compare against the raw DB every time.
You should be able to bypass it wanting to create a table by creating a new migration, deleting/commenting out the table create code in UP and table remove code in DOWN, and apply the empty migration. It'll still have the view in the generated code, so it won't try to add it again.
You can create an empty migration as the first migration with the -IgnoreChanges flag to allow Entity Framework to get a snapshot of the existing database. For example:
Add-Migration InitialMigration -IgnoreChanges
This will map your entity to already existing table or a view in your case
modelBuilder.Entity<entityname>().ToTable("Tablename");
or using data annotations like this
[Table("tablename")]
public class ClassName {
....
}
We have a Data library they have built it with CodeFirst.
Now I ran a SQL command and added a new table to that database.
But Now I want to also see its generated object class, its DBContext definitions ,etc.. in the code first code so I can use them in my LINQ queries.
So what I did was following number 3 method from this MSDN page:
https://msdn.microsoft.com/en-us/library/jj200620.aspx
But it didn't do it right. For example it did not add any definition for this new table to DBContext.cs file, for example all my other tables that used to be there are defined like this:
DbSet<Zipcode> Zipcodes { get; set; }
But it has not added anything for me.
What is the correct way to do this?
I'm unaware of a way to simply add a new table and have it 'plug-n-play' with your existing model without manual work. The two options I know of are:
Rebuild the model using Code First from DB and include your added table
Manually create the table as a class and add the DbSet and entity in the OnModelCreating method in your model
Code First from Database only works when you already have a database. If you want to add a new table, you will have to start using Code-First(alone), that means: add the entity Zipcode to the model, DbSet to the DbContext and after that when you compile it will generate de table in the database.
I had something like:
class Person
string CarModel
which in terms of database got translated to MyClass table with 'MyProperty' string column.
Now I have:
class Person
string CarId
class Car
int Id
string Model
Which EF translates to two tables: MyClass and MyNewClass, and there is Car.CarId -> pointing to Car.Id. So far so good.
I will manually take care of populating the Car table with the items that were in the Person.CarModel column. But question is: how do I migrate my data? I want the Person.CarId to point to the correct Car.Id record. I am thinking something like:
UPDATE [dbo].[Person]
SET [CarId] = cars.Id
FROM [dbo].[Cars] cars
WHERE cars.Model = [dbo].[Cars].CarModel
I am doing that between the Adding of the new column (CarId) and the drop of the old column (CarModel) from the table. However, the SQL server complains 'CarId column does not exist'. I guess it has something to do with the change being transactional.
What is the correct approach to this? I am using scripts (i.e. I am deleting my Migrations folder after I generate the .sql out of it)
I believe the best way is:
Remove old CarModel string from the model and add new Car entity to your Person, but in migration behind this instead of deleting a CarModel column rename it to [_Stale_CarModel] (naming is just for example).
Run your manual data migration script over the database, verify that data is migrated correctly - ids are set for rows that have [_Stale_CarModel] set and values are correct. You can either manually add an EF migration with your data migration code inside, or do it on your own if you need to do verification script for your data before commiting actual migrated data OR if your migration takes more than default timeout.
Create a migration for cleaning up your DB schema (EF will create empty migration for this step) and manually write DropColumn("Person", "[_Stale_CarModel]")
I am using entity framework, code first, 4.0, hitting an existing legacy database for read-only access. The database is normalized, so
Table [Event]
[ID]
[Date_Entered]
[Event_Status_Key]
Table [Event_Status]
[Event_Status_Key]
[Event_Status_Description]
My class looks like
public class Event
{
public DateTime DateEntered { get; set; }
public string StatusDescription { get; set; }
}
This is a WCF service layer application.
My two questions:
Is there any easy way to populate the status description without creating a second Dictionary-type object? I've seen questions like this: Entity Framework Mapping to Lookup table, but they seem to be focused on object to object, and I really just want a primitive. I'd prefer using the fluent API as opposed to attributes.
When the data is loaded, is any of the data cached at the code layer? Or does each check on the StatusDescription mean a separate call on the [Event_Status] table?
Edit: A possible (more subjective, which is why I didn't bring it up) third question is how close should the data entities match the database. Is it always a one-to-one field/table? Is what I'm doing (joining two tables into one data entity obejct) bad?
Thanks.
Entity framework expects that you will map both tables as separate entities and use projection in your query:
var query = from e in context.Events
select new WcfEvent // Your original Event class is just DTO
{
DateEntered = e.DateEntered,
StatusDescription = e.EventStatus.EventStatusDescription
};
This example expects correctly one-to-one mapping of your Event and Event_Status tables.
If you need any kind of caching you will have to implement it yourselves. Projected results are not even tracked by the context.
Currently I am deploying my application to a shared hosting environment and code-first with migrations has been working great except for one minor hiccup. Everytime I want to push the site I have to use the "Update-Database -script" option because I have to prepend every table name with [dbo] because by default the shared host creates a default schema name that is the same name as the database username.
If I log into my shared host and create a database, I then have to create a user. If I name that user admin, then the tables code-first creates while logged in as admin look something like this "[admin].[BlogPosts]". When the application runs all the tables are created but I get an EF exception because it says "[dbo].[BlogPosts]" is invalid. If I rename the table's schema name to "[dbo]" instead of "[admin]" that fixes it.
To get around this I have to generate a migrations script to be executed manually and add "[dbo]" in front of all the table names because the script only references the tables by their name, not by their schema and their name.
Is there an easy way to get around this? It would be so nice if all I had to do was publish the application and everything just worked. If it wasn't for the schema name discrepancy it would be a one click deploy and everything would be glorious.
For those using Entity Framework 6, just use the HasDefaultSchema method:
public class Contexto : DbContext
{
public DbSet<User> Users { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.HasDefaultSchema("MyDefaultDbSchema");
}
}
You could use the ToTable method to specify the schema name. If you do not specify the schema name, EF will by convention use dbo.
public class MyContext
{
private string schemaName = "Foo";
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<MyEntity>().ToTable("MyTable", schemaName);
}
}
In EF Code first, by default, everything is set up based on user access with a managerial access "DBO-Schema" in the SQL Server. But if a specific user is defined to work with a database that is common in shared hosting, then there will no longer be Dbo management access. This time the names of our tables are dbo.tableName, for example, someUser.tableName, and inaccuracy of this point makes it impossible to run the program. To modify and explicitly assign a user connected to a database. If you use metadata, the following method should be used:
[Table("MyTableName", Schema="MySchemaName")]
public class MyClassName
{
//Other Lines...
}
Or (Whether or not Fluent API is customizable as follows:)
modelBuilder.Entity<Blog>().ToTable("MyTableName", schemaName:"MySchemaName");
Notice the following:
a good reference for study:
http://www.c-sharpcorner.com/article/fluent-api-in-code-first-approach/
For database-first implementations, it's easy. Open the edmx file, right click -> Properties and set the default database schema.
For code-first, this article seems most promising: https://web.archive.org/web/20150210181840/http://devproconnections.com/entity-framework/working-schema-names-entity-framework-code-first-design
I would like to add since this is for C#, I have written one below for VB
Public Class ClientDbContext
Inherits DbContext
Public Property Clients As DbSet(Of Client)
Protected Overrides Sub OnModelCreating(modelBuilder As DbModelBuilder)
modelBuilder.HasDefaultSchema("dbo")
End Sub
End Class