I am trying to follow the ASP.NET Web Forms tutorial, just with a MySQL connection instead of local: ASP.NET Web Forms - Create the Data Access Layer
I already tested that the connection string works, because I made a dummy table in an existing DB and I can see it in the Server Explorer when I run the app.
But according to the tutorial, it was also supposed to create a DB and tables and seed it. But nothing happens.
This is my connection string:
<add name="myProject" connectionString="Data Source=MY_PC_NAME;User Id=testuser; Password=testpassword; Integrated Security=False" providerName="System.Data.SqlClient"/>
This is the ProjectContext file:
namespace myProject.Models
{
public class ProjectContext : DbContext
{
public ProjectContext() : base("base_name")
{
}
public DbSet<Item> Items { get; set; }
public DbSet<Category> Categories{ get; set; }
}
}
And the ProjectDatabaseInitializer:
public class ProjectDatabaseInitializer : DropCreateDatabaseIfModelChanges<ProjectContext>
{
protected override void Seed(ProjectContext context)
{
GetItems().ForEach(i => context.Items.Add(i));
GetCategories().ForEach(c => context.Categories.Add(c));
}
// some seeding lists below
I then added the initializer to the Global.asax.cs:
Database.SetInitializer(new ProjectDatabaseInitializer());
And both Items and Categories have their corresponding Item and Category models.
But when I run the app, the Server Explorer remains empty.
Note that I modified the original code of the tutorial a bit
Related
I have an ASP.NET MVC application EducationalCenter with the following structure of projects:
DbContext file is EducationalCenterContext.cs in the Data project and looks as follows:
public sealed class EducationalCenterContext: DbContext
{
public DbSet<Student> Students { get; set; }
public EducationalCenterContext( DbContextOptions<EducationalCenterContext> options)
: base(options)
{
Database.EnsureCreated();
}
}
And in Startup.cs file, the dbContext configured as follows in ConfigureService():
services.AddDbContext<EducationalCenterContext>
(options => options.UseSqlServer("Server=localhost;Database=EducationalCenterDb;Trusted_Connection=True;MultipleActiveResultSets=true"));
This is my working version to which I came by fixing errors when try to add-migration. However it seems awful to me that my web app has project reference to the Data project.
What was my first idea:
In appsettings.json I created this section :
"ConnectionStrings": {
"DefaultConnection": "Server=localhost;Database=EducationalCenterDb;Trusted_Connection=True;MultipleActiveResultSets=true"
}
Then I created AppSettings class in the Common project:
public class AppSettings
{
public string ConnectionString { get; set; }
}
Then I try to pass ConnectionString in DAL via DI:
services.Configure<AppSettings>(Configuration.GetSection("ConnectionStrings"));
And created EducationalDbContext.cs:
public sealed class EducationalCenterContext: DbContext
{
private readonly string _connectionString;
public DbSet<Student> Students { get; set; }
public EducationalCenterContext( IOptions<AppSettings>, DbContextOptions<EducationalCenterContext> options)
: base(options)
{
_connectionString = app.Value.ConnectionString;
Database.EnsureCreated();
}
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
optionsBuilder.UseSqlServer(_connectionString);
}
}
But when I try to add-migration via PM Console, I ran into this error:
Could not load assembly 'EducationalCenter.Data'. Ensure it is referenced by the startup project 'EducationalCenter'
Then I added project reference and ran into the next error:
Unable to create an object of type 'EducationalCenterContext'. For the different patterns supported at design time, see https://go.microsoft.com/fwlink/?linkid=851728
Then I added services.AddDbContext<> in Startup.cs and came to the working version which I mentioned above.
So...
Is it normal that my web app has reference to the data access project?
Is it possible to configure EF in the Data project and ensure normal separation between DAL, BLL and web app?
Putting the context and configuration in a separate project is fine.
You got the first error because "Education Center" was set as start up project but did not have reference to data project.
The second error is because the migration builder needs some connection information in the data project to resolve the connection (to compare EF state and database state) to determine what changes are needed.
First add reference in your data project to:
Microsoft.EntityFrameworkCore.Design
Then add a context factory in your data project that migration console command will discover:
internal class MyContextFactory : IDesignTimeDbContextFactory<MyContext>
{
public MyContext CreateDbContext(string[] args)
{
var dbContextBuilder = new DbContextOptionsBuilder<MyContext>();
var connString = "myconnection string";
dbContextBuilder.UseSqlServer(connString);
return new MyContext(dbContextBuilder.Options);
}
}
Question: How do I specify the Entity Framework connection string within a .NET API?
I am accustomed to creating a DAL class and specifying the base connection string like I did here.
public class LocalContext : DbContext
{
public LocalContext() : base("LocalDBContext")
{
}
public DbSet<Weapons> Weapons { get; set;
}
Which in turn grabs the LocalDBContext connection string from the web.config or appsettings.json.
"ConnectionStrings": {
"LocalDBContext": "Server=.;Database=Weapons;Trusted_Connection=True;"
},
This is what I have done in the past in various web apps but not sure if I have to do something different with an API?
I would expect it to call and save into "Weapons" at "Server=." however it instead created a new Database called "LocalDBContext" at the connection of "(localdb)\mssqllocaldb". Any tips would be greatly appreciated!
In EF core you don't need to send a connection to the base class with the constructor, just follow this approach:
public partial class LocalContext : DbContext
{
public LocalContext ()
{
}
public LocalContext(DbContextOptions<LocalContext> options) :
base(options)
{
}
public virtual DbSet<Weapon> Weapons { get; set; }
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
if (!optionsBuilder.IsConfigured)
{
//warning You can move this code to protect potentially sensitive
information
//in connection string.
optionsBuilder.UseSqlServer("Data Source= .;Initial
Catalog=Weapons;Trusted_Connection=True;");
}
}
}
The given String "LocalDBContext" is interpreted as Connectionstring, see official Documentation on DbContext(String).
Do something like:
public class LocalContext : DbContext
{
public LocalContext (DbContextOptions<LocalContext> options)
: base(options)
{
}
....
I have some questions below:
Questions:
Did you add Entity data model in your API solution?
If yes, didn't you save connection string in config file while adding EDM?
While adding EDMX in solution, model window asks to connect the database. Once EDM connects with database, it asks to save connection string in configuration file. You can add tables, functions, SPs, views. This way EDM connects with actual database rather picking different database.
Hi guys i am trying to deploy mvc application to azure. so far, ive done half of the work. so, main web application with AplicationDbContext is were my Identity2.0 tables are for user and roles and so on. Now, i have DAL class library for model and QuizContext for the rest of the application. I what to use one instance of database for storing these two contexts and as u can see from the server explorer on the left its done on localhost, but when i try to publish it on azure only mvc web project is deployed. Just to be sure ive connected with sql management studio to azure database and it only shows Identity tables. After searching for few days online to find solution i gave up cuz they are all basic stuff.
Can u help me make that happen :D My goal is to deploy web application with class library(s) and 2 DbContexts using one database on azure.
Thank u very much.
link to pictures so u get better understanding of my problem
http://testic1.azurewebsites.net/
there is no error msg. at publish console i just get project published - 1 and thats it.
this is dbcontext from class library
namespace Quiz.DAL
{
public class QuizContext : DbContext
{
public QuizContext() : base("name=DefaultConnection")
{
}
public virtual DbSet<Option> Options { get; set; }
public virtual DbSet<Question> Questions { get; set; }
public virtual DbSet<Category> Categories { get; set; }
public virtual DbSet<Test> Tests { get; set; }
}
}
this is dbcontext from mvc web application
namespace Quiz.Models
{
public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
public ApplicationDbContext()
: base("DefaultConnection", throwIfV1Schema: false)
{
}
public static ApplicationDbContext Create()
{
return new ApplicationDbContext();
}
}
}
this is connection string from mvc web project, DAL class library does not have connection string
<connectionStrings>
<add name="DefaultConnection" connectionString="Data Source=(LocalDb)\MSSQLLocalDB;AttachDbFilename=|DataDirectory|\Quiz.mdf;Initial Catalog=Quiz;Integrated Security=True" providerName="System.Data.SqlClient" />
</connectionStrings>
I've seen some of the answers in here, but nothing helped resolving the problem.
I'm following Microsoft ITAcademy tutorial on MVC Jumpstart and they teach by an example that uses EF Code-First approach.
When I'm running the application, I'm getting an error:
CREATE DATABASE permission denied in database 'master'
This is my connection string:
<add name="DefaultConnection"
connectionString="Data Source=.\SQLEXPRESS;Initial Catalog=aspnet-Conference-20150930151714;Integrated Security=true"
providerName="System.Data.SqlClient" />`
I do not post all the code in here, since it is a work through Microsoft tutorial line by line.
It fails when I call one of the controller that is supposed to have data retrieved from the database:
public ActionResult Index()
{
return View(db.Speakers.ToList());//fails here with described exception
}
This is how Database is initialized in Global.asax.cs:
using System.Data.Entity;
public class MvcApplication : System.Web.HttpApplication
{
protected void Application_Start()
{
Database.SetInitializer<ConferenceContext>(new ConferenceContextInitializer());
//the rest of code....//
}
}
This is ConferenceContext class:
using System.Data.Entity;
public class ConferenceContext : DbContext
{
//public ConferenceContext() : base("name = DefaultConnection") { }
public DbSet<Session> Sessions { get; set; }
public DbSet<Speaker> Speakers { get; set; }
}
This is a piece of code for adding dummy data to Database:
public class ConferenceContextInitializer : DropCreateDatabaseAlways<ConferenceContext>
{
protected override void Seed(ConferenceContext context)
{
context.Sessions.Add(
new Session()
{
Title = "I want Spaghetti",
Abstract = "The life and times of spaghetti lover",
Speaker = context.Speakers.Add(
new Speaker()
{
Name = "John Doe",
EmailAddress = "john.doe#test.com"
})
});
context.SaveChanges();
}
}
Can you explain me where the database is supposed to be created?
Should I have special permissions on my SQL Server for that or it is just enough to create a database in App_Data folder?
Will I be able to do create Database at all on my work PC?
You need to give your account a global server permission to create database on the server.
I'm trying to generate a database from a model. I believe I've setup everything I can find in other questions/walktroughs, but my database doesn't seem to be generated.
Context:
public class DatabaseContext : DbContext {
public DatabaseContext()
: base("Name=DatabaseContext") {
}
public DbSet<Show> Shows { get; set; }
protected override void OnModelCreating(DbModelBuilder modelBuilder) {
modelBuilder.Configurations.Add(new ShowMap());
}
}
Mapping:
public class ShowMap : EntityTypeConfiguration<Show> {
public ShowMap() {
ToTable("Shows");
// Key
// Properties
}
}
Initializer:
public class DatabaseInitializer : DropCreateDatabaseAlways<DatabaseContext> {
private List<Show> _shows = new List<Show>();
protected override void Seed(DatabaseContext context) {
LoadShows();
_shows.ForEach(s => context.Shows.Add(s));
}
private void LoadShows() {
// Creating models
}
}
Global.asax:
Database.SetInitializer(new DatabaseInitializer());
Web.config:
<add name="DatabaseContext" connectionString="Data Source=JEROEN-DESKTOP\SQLEXPRESS;Initial Catalog=NoName;Integrated Security=True;MultipleActiveResultSets=True" providerName="System.Data.SqlClient" />
I have manually created the schema 'NoName' without adding tables. Executing my program goes without problems, but no table is generated. When I look at the connections in the VS SQL server object explorer I can see both localdb and SQLEXPRESS don't contain any relevant tables.
Another thing to note: I have added EntityFramework to my project using nuget, but when I rightclick on any file/folder, I don't see EntityFramework in the context menu. Could this be the issue? I've removed and added EF to the project, but it's still not showing up. There's an 'EntityFramework' entry in my References folder though.
I would start looking at a few things, permissions being one. Make sure the delegating caller can actually create on this database. Also validate that EF is access the database during debugging : base("name=DatabaseContext"). If you can access the database, IntelliTrace will give you the out put statements it is creating.
Also, I would validate migrations is enabled. Using Nuget Package Manager Console run, Enable-Migrations.The full tutorial is Building an Initial Model & Database