Data table is not generated when I attempt to add a connection - database

I'm following a guide for creating a simple code-first MVC, which uses data context scaffolding. After creating a model class file and adding a scaffolded item to the project, it instructs me to go to server explorer, hit "new connection", enter (localdb)\mssqllocaldb and from there, select my database name (PlanetContext (CodeFirstFinal.Models). After hitting "ok", I should be able to expand the tables in my server explorer and see the planet data table. However, my tables folder is empty. I followed the tutorial to the letter, so I'm unsure why this is happening.
Here is the code in my model:
namespace CodeFirstFinal4.Models
{
public class Planet
{
public int PlanetID { get; set; }
public string Name { get; set; }
}
public class PlanetContext: DbContext
{
public DbSet<Planet> Categories { get; set; }
}
}
As this is a very simple app, this is the only code so far, besides the scaffolded view. (For that, I right-clicked my project, selected "add scaffolded item" and MVC 5 Controller with views using EntityFramework. I then entered my model class, which is:
Planet (CodeFirstFinal4.Models)
and my data context class, which is: PlanetContext (CodeFirstFinal4.Models).
I'm not sure how helpful this information is, but I'm including it in case it helps. I'm pretty sure that the MvcScaffolding package is installed correctly, as well as EntityFramework. However, I simply can't get the data table to be generated after right clicking 'connect to database' under server explorer, entering my local server name, and selecting the database. Below is a screenshot of the tutorial, where his table shows up under the tables folder, within server explorer. Does anyone know what might be causing the failed generation of my own data table?

Related

Change SQL Server Connection String Dynamically inside an ASP.Net Core application

I open one database at the start, then need to open another database based on user selecting two values. The database selection has to be at run-time and will change every time.
Have tried to access the Connection String using the Connection String class and have tried other options like Singleton which I do not understand. I am running this on a local Windows 10 system running SQL Server Express. Am coding using Asp.Net Core 2.1
> ASP.Net Core v2.1
Building multi tenant, multi year application
Every client will have one SQL DATABASE per year
I hope to have a table with the following structure
COMPANY_CODE VARCHAR(3),
COMPANY_YEAR INT,
COMPANY_DBNAME VARCHAR(5)
Sample Data
COMPANY_CODE: AAD
COMPANY_YEAR: 19
COMPANY_DB: AAD19
COMPANY_CODE: AAD
COMPANY_YEAR: 18
COMPANY_DB: AAD18
COMPANY_CODE: AAD
COMPANY_YEAR: 17
COMPANY_DB: AAD17
So, every company will multiple rows - one for each financial year.
The COMPANY_DB column will store the DB name to open for that session.
Once the user is authenticated, I want to change the connection string to point to the database in the COMPANY_DB column of the selected row and then let the logged in user perform transactions.
I am unable to figure out how to change the connection string that is embedded in startup.cs.
Any tips on how to achieve this will be most appreciated.
I figured out that you are using one DbContext class for each database. See here for more information: docs.
Remove AddDbContext from Startup, remove OnConfiguring from DbContext and pass options to the constructor.
public class BloggingContext : DbContext
{
public BloggingContext(DbContextOptions<BloggingContext> options)
: base(options)
{ }
public DbSet<Blog> Blogs { get; set; }
}
Then, write service providing DbContext:
public interface IBlogContextProvider
{
BlogContext GetBlogContext(string connectionString);
}
public class BlogContextProvider : IBlogContextProvider
{
BlogContext GetBlogContext(string connectionString)
{
var optionsBuilder = new DbContextOptionsBuilder<BloggingContext>();
optionsBuilder.UseSqlServer(connectionString);
return new BlogContext(optionsBuilder);
}
}
Add service in your Startup.cs:
services.AddScoped<IBlogContextProvider, BlogContextProvider>();
Now you can use DI:
public class HomeController : Controller
{
private IBlogContextProvider _provider;
public HomeController(IBlogContextProvider provider)
{
_provider = provider;
}
public ActionResult Index()
{
using (var context = _provider.GetBlogContext(<your connection string>))
{
//your code here
}
return View();
}
}
EDIT: Of course, you can write ContextProvider as generic.

Code first migrations database error

I used this pluralsight video on MVC code first migrations to keep my default MVC IdentityDb context and create another context for custom tables. Since then I get an error trying to connect connecting to the database online:
CREATE DATABASE permission denied in database 'master'.
.........
It works locally. My connection string are correct and my context classes point to the right connection string name:
public class IdentityDb : IdentityDbContext<ApplicationUser>
{
public IdentityDb()
: base("DefaultConnection", throwIfV1Schema: false)
{
}
public static IdentityDb Create()
{
return new IdentityDb();
}
}
public class CustomDb : DbContext
{
public CustomDb() : base("DefaultConnection") { }
public DbSet<Inquiry> Inquiry { get; set; }
public DbSet<Product> Product { get; set; }
}
Connection string:
<add name="DefaultConnection" connectionString="server=***.db.1and1.com; initial catalog=***;uid=***;pwd=***" providerName="System.Data.SqlClient" />
I've read that the connection string name should be the same as the context class name but since I have two contexts I need a common name (DefaultConnection) which I've specified in the contexts.
It works connecting to my local database but not when its online so I did wonder if this would relate to the migration history table being up to date online and EF 6 trying to update the database but the entries in the migrations table match.
Any help appreciated.
* UPDATE *
I tried resetting the EF migrations with this guide thinking if the migrations where out of sync with the online DB it could result in EF trying to re-create the database causing this issue. However the problem still persists!
I have now added these lines to my context constructors respectively:
Database.SetInitializer<IdentityDb>(null);
Database.SetInitializer<CustomDb>(null);
This has stopped the error but kind of defeated the purpose of EF because I now have to remove it when creating migrations and manually script the changes to the online DB, then put it back in for the site to work online.

Entity Framework not creating Tables

I really have no luck with the EF every time. This time it looks like this:
First time i created a context i had an error like:
Invalid object name 'dbo.TableName1'
After this setting the Database Initializer to CreateDatabaseIfNotExists T it did the trick.
Next i created a different context, which was changed at some point of the development. So this time i keep getting this error:
The model backing the 'NewContext' context has changed since the database was created.
I found a solution to set the Database Initializer to null, but after this i keep getting the first error:
Invalid object name 'dbo.TableName2'
I also tried to set the the initializer to DropCreateDatabaseIfModelChanges and DropCreateDatabaseAlways, and these settings throw the exception:
Cannot drop database "DatbaseName" because it is currently in use
I think I already tried everything i found on the Web (there are many topics of this kind) but none helped me with it.
Dropping the Database didn't help, nor changing from Local File Database to SQL Server 2014 Exspress. The same exception is thrown. Any ideas?
Edit1:
Working context:
public class ProfilesContext : DbContext
{
public ProfilesContext() : base("DefaultConnection")
{
}
public DbSet<Profile> Profiles { get; set; }
public DbSet<PrevilegedContact> PrevilegedContacts { get; set; }
}
Failing context:
public class PlacesContext : DbContext
{
public PlacesContext()
: base("DefaultConnection")
{
}
public DbSet<Place> Places { get; set; }
public DbSet<Price> Prices { get; set; }
public DbSet<Photo> Photos { get; set; }
public DbSet<Comment> Comments { get; set; }
}
For what you are doing, it seems you have 2 options for your initializer. There is Migrations and there is DropCreateDatabaseIfModelChanges.
Migrations will give control over updating the database tables when your models change and allow you to preserve data. You can configure it to allow data loss or not. Very useful during development time if you already have test data in there.
DropCreateDatabaseIfModelChanges will simply drop the database each time you make model changes and recreate it with the new schemas.
You are getting the error message
Cannot drop database "DatbaseName" because it is currently in use
because you have more than likely browsed the table in your server explorer and have an open connection to the database. You can close the connection using the right click context menu in server explorer.
If you want a video overview on Migrations there is a free video by Scott Allen & Pluralsight. This is MVC4 but the Entity Framework section does cover Initalizers. If you want an updated one for MVC5 to include multiple Contexts etc, it does exist but you would need to take the Pluralsight free trial to get access to it.
I agree with James. Good point about checking Server Explorer. Right-click the database and choose Close Connection or at least check that there is a red X indicating the connection is closed. The link below is a great tutorial on the basics with Code First Migrations. The link is directly to the page within the tutorial that talks about making model changes and how to make EF happy again! http://www.asp.net/mvc/tutorials/mvc-5/introduction/adding-a-new-field. I prefer using Migrations. You would use the Package Manager Console and 1) Enable Migrations, 2) Add a migration, 3) Update the database. If in development, use LocalDb if possible, and use the Seed method in the Configuration class to prepopulate the database.

EntityFramework unit test example

I just solved my own question, but thought I'd might still be helpful for others to read so decided to post it anyway.
I am trying to get started with azure development and am currently at the stage of getting the database up and running. After a few hickups I achieved the following:
installed VS2012, MSSQLSERVER2012, Azure SDK .NET, EntityFramework 6.0.0 alpha and a bunch of other things
wrote my first entities (code first) and generated a database out of it.
The last thing I'd like to see before I pick up the next challenge is to actually add something to my newly created database first. I'd thought the easiest way would be writing a test in nunit.
Here's what I got so far...
The entity class User:
namespace Models.Users
{
public class User
{
public int Id { get; set; }
public string Name { get; set; }
public string EmailAddress { get; set; }
}
}
The entity class UsersDb:
using System.Data.Entity;
namespace Models.Users
{
public class UsersDb : DbContext
{
public DbSet<User> Users { get; set; }
}
}
Generated the database with the following PS commands:
enable-migrations -ProjectName Models -ContextTypeName Models.Users.UsersDb
add-migration -ProjectName Models Initial
update-database -ProjectName Models
Finally, I wrote the following unit test
using Models.Users;
using NUnit.Framework;
namespace Tests
{
[TestFixture]
public class DatabaseTests
{
[Test]
public void AddUserTest()
{
var users = new UsersDb();
var user = new User
{
Id = 1,
Name = "test",
EmailAddress = "test#gmail.com"
};
users.Users.Add(user);
users.SaveChanges();
}
}
}
That test runs, but throws an exception I can't figure out.
System.InvalidOperationException : The Entity Framework provider type 'System.Data.Entity.SqlServer.SqlProviderServices, EntityFramework.SqlServer, Version=6.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' for the 'System.Data.SqlClient' ADO.NET provider could not be loaded. Make sure the provider assembly is available to the running application. See http://go.microsoft.com/fwlink/?LinkId=260882 for more information.
Solution
What I had to do to solve this, is open NuGet management (right click solution) and press the manage button on EntityFramework. In the dialog add a checkbox in front of your test solution, rebuild and go.
Now, I have a very small solution that creates a new user via a unit test and saves it into my database. A nice startup project which I can now start extending.
Solved the question while typing the question itself. Thought i'd still be useful as a reference for others.

Integration tests with Entity Framework 4 Code First using SQL Server CE 4 or SQLite

I would like to start with integration testing. I am using an ASP.NET MVC 3 app. And I am using Entity Framework 4 Code First CTP5. My integration tests to the database is in a separate project something like MyProject.Data.IntegrationTests.
I am planning on using SQL Server CE 4 or SQLite. Any recommendations/tips/opinions on using any one of these for what I am trying to accomplish?
Does anyone know of any decent articles that I can read on what I am trying to accomplish? And help/feedback would be appreciated.
I am using SQL Server 2008 for my database. But when testing my repositories I would like to test them against one of these database mentioned above, so I will need to specify the connection string.
UPDATE
I work from a service layer (called from my controller) and then the service layer will call my repository. For examples, below is how I would add a news item:
Service class:
public class NewsService : INewsService
{
private INewsRepository newsRepository;
public NewsService(INewsRepository newsRepository)
{
this.newsRepository = newsRepository;
}
public News Insert(News news)
{
// Insert news item
News newNews = newsRepository.Insert(news);
// Insert audit entry
// Return the inserted news item's unique identifier
return newNews;
}
}
Repository class:
public class NewsRepository : INewsRepository
{
MyContext context = new MyContext();
public NewsRepository()
{
}
public News Insert(News news)
{
int newsId = context.Database.SqlQuery<int>("News_Insert #Title, #Body, #Active",
new SqlParameter("Title", news.Title),
new SqlParameter("Body", news.Body),
new SqlParameter("Active", news.Active)
).FirstOrDefault();
news.NewsId = newsId;
// Return the inserted news item
return news;
}
}
I am using Entity Framework 4 Code First CTP5 and NUnit. Does NUnit has something similar to the roll back in XUnit?
If you use a testing framework like XUnit (http://xunit.codeplex.com/), it comes with a feature called [AutoRollback] and that will rollback the transaction ran in the test so none of your data will change!
As far as how to setup the tests, I need to see more of how you setup your data access. Did you use the Repository Pattern? (Entity Framework 4 CTP 4 / CTP 5 Generic Repository Pattern and Unit Testable). If I could see some of your code it would help. Below is a sample integration test with XUnit:
private readonly IUserRepository _repository;
public UserRepositoryTests()
{
_repository = new UserRepository(base._databaseFactory);
}
[Fact, AutoRollback]
public void Should_be_able_to_add_user()
{
var user = new User{Name = "MockName"};
_repository.Add(user);
base._unitOfWork.Commit();
Assert.True(user.Id > 0);
}
So the above test adds a user to my database, then checks its Id property to check that SQL Server auto generated an Id for it. Because the method is decorated with the AutoRollback attribute, the data is then removed from my database after the method ends!

Resources