That solution does not work in .net core 2 tied to SQL Server 2016. Original Question: Trying to jump into entity framework, using the "Code First Approach". I have my new class setup “NewTable” shown below. I can’t figure out what in the Program Manger Console I need to type to get this table created in my Default Connection String (pointing to a local instance of Sql Server 2016). The database is working and the user in this .net core 2 web app can register his/her name then log in using that new created account. Thanks in advance!!
Default Connection String:
"ConnectionStrings": {
"DefaultConnection" "Server=localhost\RCDSE_Dev;Database=Some Database;User ID=sa;Password=SomePass;"
},
[Table("NewTable")]
public class NewTable
{
[DatabaseGenerated(DatabaseGeneratedOption.Identity)] //Database generated key
[Key] //Primary Key
public long Id { get; set; }
[Required]
public string Manager { get; set; }
}
public class NewTableContext : DbContext
{
public DbSet<NewTable> NewTables{ get; set; }
}
Add a constructor to the DbContext as below:
public class NewTableContext : DbContext
{
public DbSet<NewTable> NewTables{ get; set; }
public NewTableContext() : base("DefaultConnection") { }
}
I figured this out. Will post a detailed step by step guide for others in the next couple of days. There are specific things that need to be done in .net core 2 project file that were NOT COVERED in any of the referenced examples by users here. Thanks for all the help..it got me somewhat pointed in a direction, to find the right direction...lol.
Related
I'm working on C# winForms project (.NET 5.0) , Iam a newbie in EntityFramework code first, I worked with EF DB First many times but I decide to go through EF Code First.
My Class
class Student
{
public int ID { get; set; }
public string Name { get; set; }
}
My Db Context class I created
class XMDBContext:DbContext
{
public XMDBContext() : base()
{
}
public DbSet<Student> Students { get; set; }
}
Now I want to know how can I use Visual Studio or Entity Framework to generate the database(preferred if in SQL Server) from these classes ?
There are different ways to create the database in a code first scenario. But the easiest approach would be to just run your application and read or write to the DbContext. It will then automatically create the database "on access".
The official microsoft example is also very helpful if you are doing this the first time: Code First to a New Database
Created new project in .net core 2.2 and installed nuget package linq2db.sqlserver using this package i am able to do CRUD with database first approach but i need to know how to do CRUD using code first approach.
Linq2Db has a link https://linq2db.github.io/index.html
which provides more information about how to create a POCO and create a table based on it.
As per the page, a simple POCO can go like this:
using System;
using LinqToDB.Mapping;
[Table(Name = "Products")]
public class Product
{
[PrimaryKey, Identity]
public int ProductID { get; set; }
[Column(Name = "ProductName"), NotNull]
public string Name { get; set; }
// ... other columns ...
}
Then you need to configure the connection strings.
I have a very basic model class
class Student
{
public int StudentID { get; set; }
public string Ad { get; set; }
public string Soyad { get; set; }
}
and a very basic DbContext class
class StudentContext: DbContext
{
public StudentContext() :base("StudentDB")
{
}
public DbSet<Student> Students { get; set; }
}
I've tried with both a console app and also an ASP.NET MVC 5 project. Neither worked :/
When I build and run the application no database gets created. When I examine, I realized that although I even passed a parameter for DB Name in the base constructor, no connection string is inserted into app.config or web.config.
The Entity Framework Nuget package was installed before each trial and EF worked fine for my previous database first projects. I have no idea why I can't create database at first run. I even tried to add following line in Main() function of console project:
StudentContext ctx = new StudentContext();
ctx.Database.CreateIfNotExists();
Did not work :/
Where does it say that the DbContext(string) would create a connection string in app.config? The remarks section of the DbContext class describes the connection string. But is says nowhere that the DbContext class would adjust app.config.
Changing the app.config would be undesired behaviour. What if you want the same DbContext to control two similar databases, for instance to copy data from one database to the other?
To get the the connection string after creating a DbContext instance use:
dbContext.Database.Connection.ConnectionString;
If you want to write the connection string to the App.Config, I'd suggest you'll write an extension function for it:
static class DbContextExtensions
{
public static void SaveConnectionString (this DbContext dbContext)
{
string connectionString = dbContext.Database.Connection.ConnectionString;
SaveConnectionString(connectionString);
}
private static void SaveConnectionString(string connectionString)
{ // save the string where you want it, for instance app.config
// out of scope of this question
}
}
usage
using(var dbConext = new StudentContext("...");
{
dbContext.SaveConnectionString();
}
Alternate option would be - "Initializer". If you want to create database on application start either use:
context.Database.Initialize(true);
but you can't use when you're using "Initializer"
ctx.Database.CreateIfNotExists();
My problem lies in the lack of experience in MVC. Basically, I have two tables in DB
-Person
-Offer
For each I have created a model and a controller and a model, so the structure looks like that:
public class Offer
{
public int OfferID { get; set; }
public string OfferTitle { get; set; }
public string State { get; set; }
public string Description { get; set; }
}
public class OfferDBContext : DbContext
{
public DbSet<Offer> Offers { get; set; }
}
This is the Offer model.
public class Person
{
public int PersonID { get; set; }
public string Username { get; set; }
public DateTime Birthday { get; set; }
public string Education { get; set; }
public string Email { get; set; }
}
public class PersonDBContext : DbContext
{
public DbSet<Person> Persons { get; set; }
}
This is the Person model.
Firstly I created the Person model, that added itself to db without any problems. Then I wanted to add Offer table, and I had to use the DropCreateDatabaseIfModelChanges method. I used it for OfferInitializer and PersonInitializer and then there is the Global.asax.cs file
protected void Application_Start()
{
Database.SetInitializer<OfferDBContext>(new OfferInitializer());
Database.SetInitializer<PersonDBContext>(new PersonInitializer());
//Database.SetInitializer<PersonDBContext>(new PersonInitializer());
AreaRegistration.RegisterAllAreas();
RegisterGlobalFilters(GlobalFilters.Filters);
RegisterRoutes(RouteTable.Routes);
}
From what I understand, I cant do that simply because I am dropping database 2 times, each time populating only one table at a time. How do I reorganize it all, so that I can populate both or more tables at a time, or the whole database?
First things first, you should not create individual DbContext classes for each table. You should instead put all your DbSets in the same DbContext. Doing this will simplify things greatly for you.
Secondly, you should look into using migrations. You should start using them very early in your project.
You work with code first migrations using the Package Management Console.
enable-migrations
Does exactly what the name implies. Initializes migrations in your project. This will create a folder inside your project and generate the files needed.
add-migration InitialCreate
This creates a migration. InitialCreate is actually a string and you can change it to whatever you want. This command will generate the scripts needed to create the database from strach.
update-database
This command verifies the database and applies the migration (or migrations - there can be multiple) required in order to get the database up-to-date.
This is the initial setup. If you do further changes to your first code first classes, or add more, you will just have to add a new migration and then execute it.
add-migration AddedFirstName
update-database
It's that simple!
There are some more advanced concepts like seed, rollback, update to specific migration, etc., but what I have typed above covers the basics and the day to day usage of migrations.
I recommend you to read this article which explains everything in much more detail: http://www.asp.net/mvc/overview/getting-started/getting-started-with-ef-using-mvc/migrations-and-deployment-with-the-entity-framework-in-an-asp-net-mvc-application
I have an Azure Mobile Services project (C# backend) that I recently created and attached to an Azure SQL database. I have been trying to enable Code-First Migrations on that backing database, but it throws errors when I try to update the database.
I ran through all of the conventional steps to enable migrations (Enable-Migrations, Add-Migration). But when I try to Update-Database, it returns the following error:
Cannot create more than one clustered index on table 'dbo.Appointments'. Drop the existing clustered index 'PK_dbo.Appointments' before creating another.
Why is this happening? There aren't any tables in my database, and the project is pretty much the default.
Several of the answers about deriving from a custom entity class will work, but they are not the ideal solution. As the EF team (and others) have mentioned, you need to simply add this line to your Context Configuration constructor.
SetSqlGenerator("System.Data.SqlClient", new EntityTableSqlGenerator());
This will remove your errors when creating migrations and allow you to update the database via powershell command.
If you are getting this error on update-database after creating the migration class, Then have a look # your migration class. The migration class will take primary is clustered index. So remove that from the up() method.
.PrimaryKey(t => t.Id, clustered: false)
.Index(t => t.CreatedAt, clustered: true);
If you using it on azure mobile service, do not call 'update-database' manually.
refer http://azure.microsoft.com/en-in/documentation/articles/mobile-services-dotnet-backend-how-to-use-code-first-migrations/
I was fighting with this problem today for a few hours. Until I found this link:
How to make data model changes to a .NET backend mobile service
If you follow the instructions there, it will definitely work. The main thing is, that the migration will take place, when you hit F5 during a local debugging session.
I just had the same issue.
It is caused by the definition of EntityData that is our base class:
public class OrgTest : EntityData
{
public string Prop1 { get; set; }
}
I replaced EntityData with my own implementation "CustomEntity" where I removed the attribute [Index(IsClustered = true)] on the CreatedAt column:
public abstract class CustomEntity : ITableData
{
// protected CustomEntity();
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
[TableColumn(TableColumnType.CreatedAt)]
public DateTimeOffset? CreatedAt { get; set; }
[TableColumn(TableColumnType.Deleted)]
public bool Deleted { get; set; }
[Key]
[TableColumn(TableColumnType.Id)]
public string Id { get; set; }
[DatabaseGenerated(DatabaseGeneratedOption.Computed)]
[TableColumn(TableColumnType.UpdatedAt)]
public DateTimeOffset? UpdatedAt { get; set; }
[TableColumn(TableColumnType.Version)]
[Timestamp]
public byte[] Version { get; set; }
}
and now I inherit from this one:
public class OrgTest : CustomEntity // EntityData
{
public string Prop1 { get; set; }
}
Probably I will have troubles further on, but for the time being I can create my model!
Hope you can also start like this!
See this article:
avoid nightmares using ef first migration in azure mobile services
EntityData define a cluster indext to CreateAt and Id is by default a cluster index, this way it provide an error and you should define only one.