Entity Framework and using a specific database - c#

My Database Team created a database called XMEN.
I need to use that specific database with my project. I have full admin rights on that database but not on the server (they won't give it to me).
CREATE DATABASE permission denied in database 'master'.
When I run my project, I get the error above because I don't have permission to create a database. How can I use entity frameworks to specify which database to use? I want Entity Framework to manage everything else (tables, relationships, etc)
------------- UPDATED 9/17/2020 - 9:12 AM EST
public class XmenContext : DbContext
{
//public XmenContext(DbContextOptions<XmenContext> options)
// : base(options)
//{
//}
public XmenContext() : base("XmenDatabase")
{
}
Now I get an error saying cannot convert from String to Microsoft.EntityFrameworkCore.DbContextOptions
I clicked the link in your answer.

You should add the database name to the connection string in your configuration file.
If you need some help you can view here :
https://learn.microsoft.com/en-us/ef/ef6/fundamentals/configuring/connection-strings
If you are having trouble add your connection string to the question (without sensitive information) and I will try to help.
Good luck !

Related

Change ASP.NET Identity to use existing database

I'm using ASP.NET MVC 5 with a Database-First workflow. I've created the Identity tables (AspNetUsers, AspNetRoles etc.) in my existing database however I'm having problems getting the register and login functionality to work properly.
This is the IdentityModels.cs class
public class ApplicationDbContext : IdentityDbContext<ApplicationUser>
{
public ApplicationDbContext()
: base("MyConnectionString") // I use "MyConnectionString" instead of "DefaultConnection"
{
}
This is what the EF connection string from the web.config looks like
<connectionStrings><add name="MyConnectionString" connectionString="metadata=res://*/Entities.MyModel.csdl|res://*/Entities.MyModel.ssdl|res://*/Entities.MyModel.msl;provider=System.Data.SqlClient;provider connection string="data source=My-Pc\SQLEXPRESS;initial catalog=MyExistingDatabase;integrated security=True;MultipleActiveResultSets=True;App=EntityFramework"" providerName="System.Data.EntityClient" />
And for good measure here's the context class generated from the edmx
public partial class MyConnectionString : DbContext
{
public MyConnectionString()
: base("name=MyConnectionString")
{
}
To me all seems well and it should be able to create users in the database however I'm getting the following error when logging in or trying to register respectively:
For login:
The entity type ApplicationUser is not part of the model for the
current context
Line 73: var result = await SignInManager.PasswordSignInAsync(model.Email,
model.Password, model.RememberMe, shouldLockout: false);
Exception Details: System.InvalidOperationException: The entity type
ApplicationUser is not part of the model for the current context.
For register:
The entity type ApplicationUser is not part of the model for the
current context
Line 155: var result = await UserManager.CreateAsync(user,
model.Password);
Exception Details: System.InvalidOperationException: The entity type
ApplicationUser is not part of the model for the current context.
Most articles around seems to be focusing on Code-First and how to go from LocalDb to SQLExpress etc. and how to change the connection string however I haven't been able to solve this problem for a good amount of time.
Edit, solution: As #ChrFin mentioned you could use them both side by side which is what I ended up doing. I simply added a new regular connection string in web.config and let it point to the existing database. PS. remember that the connection string name cannot be the same as the existing one and must be the same you provide to the ApplicationDbContext constructor.
I THINK this scenario is not supported by ASP.NET Identity as it needs a DbContext which extends IdentityDbContext<ApplicationUser> (or similar).
Why are you forcing Identity into your DB-First context?
You can use a Code-First context for Identity alongside your other DB-First context without problems...
You can resolved this problem by following these steps:
1-create aspnetuser etc tables on your database (whatever DB you want
to use)
simply connect the application with that database not using entity framework, i'm saying just simple connection.
you will find connection string in web.config file.
place this connection string into identity model clsss
your Register and Token methods now running
now you can use entity framewoek for rest of your tables by data first approach

The entity type <type> is not part of the model for the current context

I am getting into the Entity Framework, but I am unsure if I am missing a critical point in the code-first approach.
I am using a generic repository pattern based on the code from https://genericunitofworkandrepositories.codeplex.com/ and have created my entities.
But when I try to access or modify the entity I run into the following:
System.InvalidOperationException: The entity type Estate is not part
of the model for the current context.
It happens when I am trying to access it from my repository:
public virtual void Insert(TEntity entity)
{
((IObjectState)entity).ObjectState = ObjectState.Added;
_dbSet.Attach(entity); // <-- The error occurs here
_context.SyncObjectState(entity);
}
The database (./SQLEXPRESS) is created just fine, but the entities (tables) is just not created on startup.
I am wondering if I need to explicit set the mapping of the entities? Is EF not able to this by its own?
My Entity is:
public class Estate : EntityBase
{
public int EstateId { get; set; }
public string Name { get; set; }
}
My context is as so:
public partial class DimensionWebDbContext : DbContextBase // DbContextBase inherits DbContext
{
public DimensionWebDbContext() :
base("DimensionWebContext")
{
Database.SetInitializer<DimensionWebDbContext>(new CreateDatabaseIfNotExists<DimensionWebDbContext>());
Configuration.ProxyCreationEnabled = false;
}
public new IDbSet<T> Set<T>() where T : class
{
return base.Set<T>();
}
}
Is there any specific reason why this error occurs? I have tried enable migrations and enable automatic migrations without any help either.
Put this in your custom DbContext class:
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Estate>().ToTable("Estate");
}
If your tables are not created on startup, this is why. You need to tell the DbContext about them in the OnModelCreating method override.
You can either do custom per-entity mappings here, or separate them out into separate EntityTypeConfiguration<T> classes.
Apparently, this error is very generic, it could have a number of reasons. In my case, it was the following: The connection string (in Web.config) generated by the .edmx was invalid. After almost a day of trying everything, I changed the connection string from the EF string to an ADO.NET string. This solved my issue.
For example, the EF string looks something like this:
<connectionStrings>
<add name="BlogContext"
connectionString="metadata=res://*/BloggingModel.csdl|
res://*/BloggingModel.ssdl|
res://*/BloggingModel.msl;
provider=System.Data.SqlClient
provider connection string=
"data source=(localdb)\v11.0;
initial catalog=Blogging;
integrated security=True;
multipleactiveresultsets=True;""
providerName="System.Data.EntityClient" />
</connectionStrings>
And the ADO.NET string looks like this:
<connectionStrings>
<add name="BlogContext"
providerName="System.Data.SqlClient"
connectionString="Server=.\SQLEXPRESS;Database=Blogging;
Integrated Security=True;"/>
</connectionStrings>
Source: http://msdn.microsoft.com/nl-nl/data/jj556606.aspx
For me the issue was that I had not included the Entity Class within my db set inside the context for entity framework.
public DbSet<ModelName> ModelName { get; set; }
You may try removing the table from the model and adding it again. You can do this visually by opening the .edmx file from the Solution Explorer.
Steps:
Double click the .edmx file from the Solution Explorer
Right click on the table head you want to remove and select "Delete from Model"
Now again right click on the work area and select "Update Model from Database.."
Add the table again from the table list
Clean and build the solution
The problem may be in the connection string. Ensure your connection string is for SqlClient provider, with no metadata stuff related to EntityFramework.
My issue was resolved by updating the metadata part of the connection string. Apparently it was pointing at the wrong .csdl / .ssdl / .msl reference.
I've seen this error when an existing table in the database doesn't appropriately map to a code first model. Specifically I had a char(1) in the database table and a char in C#. Changing the model to a string resolved the problem.
One other thing to check with your connection string - the model name. I was using two entity models, DB first. In the config I copied the entity connection for one, renamed it, and changed the connection string part. What I didn't change was the model name, so while the entity model generated correctly, when the context was initiated EF was looking in the wrong model for the entities.
Looks obvious written down, but there are four hours I won't get back.
For me the issue was that I used the connection string generated by ADO.Net Model (.edmx). Changing the connection string solved my issue.
This can also occur if you are using a persisted model cache which is out of date for one reason or another. If your context has been cached to an EDMX file on a file system (via DbConfiguration.SetModelStore) then OnModelCreating will never be called as the cached version will be used. As a result if an entity is missing from your cached store then you will get the above error even though the connection string is correct, the table exists in the database and the entity is set up correctly in your DbContext.
The message was pretty clear but I didn't get it at first...
I'm working with two Entity Framework DB contexts sysContext and shardContext in the same method.
The entity I had modified\updated is from one context but then I tried to save it to the other context like this:
invite.uid = user.uid;
sysContext.Entry(invite).State = EntityState.Modified;
sysContext.SaveChanges(); // Got the exception here
but the correct version should be this:
invite.uid = user.uid;
shardContext.Entry(invite).State = EntityState.Modified;
shardContext.SaveChanges();
After passing the entity to the correct context this error went away.
I was facing the same issue with EntityFrameworkCore trying to update a range of values.
This approach did not work
_dbSet.AttachRange(entity);
_context.Entry(entity).State = EntityState.Modified;
await _context.SaveChangesAsync().ConfigureAwait(false);
After adding UpdateRange method and removing attach and entry everything work
_dbSet.UpdateRange(entity);
await _context.SaveChangesAsync().ConfigureAwait(false);
Sounds obvious, but make sure that you are not explicitly ignoring the type:
modelBuilder.Ignore<MyType>();
map of the entity (even an empty one) added to the configuration will lead to having the entity type be part of the context. We had an entity with no relationship to other entities that was fixed with an empty map.
if you are trying DB first then be sure that your table has primary key
Visual Studio 2019 seems to cause this for me. I fixed it by generating the edmx model again in 2017.
For me it was caused because I renamed the entity class.When I rolled it back it was Ok.
I had this
using (var context = new ATImporterContext(DBConnection))
{
if (GetID(entity).Equals(0))
{
context.Set<T>().Add(entity);
}
else
{
int val = GetID(entity);
var entry = GetEntryAsync(context, GetID(entity)).ConfigureAwait(false);
context.Entry(entry).CurrentValues.SetValues(entity);
}
await context.SaveChangesAsync().ConfigureAwait(false);
}
This was in an async method, but I've forgot to put await before GetEntryAsync, and so I got this same error...
Make sure you have set up your mapping class to point to your SQL table
I've had the same problem and in my case, the reason why I got this error message was that the property identifiers in my class file did not match the identifiers defined in the database, e.g. I wrote an identifier with a beginning uppercase letter while in the database it was all lowercase.
I've faced this issue after publishing my project using web deploy. It happened because my the metadata in connection string of my publish profile was not same as connection string in my project because I dropped the edmx for some reason and added it back with different Name. To fix it I had to delete the publish profile and redeploy again so that the metadata matches the names.
With models created from database (First Database), it is not possible to replace the connection string (with metadata and providerName="System.Data.EntityClient", from EDMX) by one of SQL.
The only possibility I have found is to create another context that uses the SQL connection (providerName="System.Data.SqlClient")
<connectionStrings>
<add name="DefaultConnection" providerName="System.Data.SqlClient" connectionString="Max Pool Size=10000;Pooling=true;Data Source=MyIpServer;Initial Catalog=myDatabase;Persist Security Info=True;User ID=MyUser;Password=MyPassword;TrustServerCertificate=False" />
<add name="Entities" providerName="System.Data.EntityClient" connectionString="metadata=res://*/Datos.MyModel.csdl|res://*/Datos.MyModel.ssdl|res://*/Datos.MyModel.msl;provider=System.Data.SqlClient;provider connection string="Max Pool Size=10000;Pooling=true;data source=MyIpServer;initial catalog=myDatabase;persist security info=True;user id=MyUser;password=MyPassword;trustservercertificate=False;MultipleActiveResultSets=True;App=EntityFramework"" />
</connectionStrings>
With the two context options, with Identity:
public partial class ContextWithUsers : IdentityDbContext<MyUser>
{
public ContextWithUsers() : base("name=DefaultConnection")
{
}
}
public class MyUser : IdentityUser
{
// aditional table user data
//public virtual MyUserInfo MyUserInfo { get; set; }
}
Normal context:
public partial class ContextWithoutUsers : DbContext
{
public ContextWithoutUsers () : base("name=Entities")
{
}
}
This solution works, but... Why is it not possible to use the same context with the First Database model + Identity ?
NOTE 1: if you force change connection string show:
System.Data.Entity.Infrastructure.UnintentionalCodeFirstException: 'The context is being used in Code First mode with code that was generated from an EDMX file for either Database First or Model First development. This will not work correctly. To fix this problem do not remove the line of code that throws this exception. If you wish to use Database First or Model First, then make sure that the Entity Framework connection string is included in the app.config or web.config of the start-up project. If you are creating your own DbConnection, then make sure that it is an EntityConnection and not some other type of DbConnection, and that you pass it to one of the base DbContext constructors that take a DbConnection. To learn more about Code First, Database First, and Model First see the Entity Framework documentation here: http://go.microsoft.com/fwlink/?LinkId=394715'
NOTE 2: External Class library with EDMX + Data and ASP.NET webform project
Delete the .edmx file and add it again. Especially, if you have upgraded the Entity Framework.
Could be stupid, but if you only got this error on some Table, dont forget to clean your project and rebuild (could save a lot of time)

MVC5 Changing database connection string at runtime

I am looking at using MVC5 to compliment an existing ASP.Net application (that is not MVC).
The app has been configured using database first.
I need to change the database connection string at runtime depending on who is logged in. (This is easy to do in the current app through data adapters).
There are over 1000 existing databases and more can created at runtime - so Web.config is not an option. Schema is common to all databases.
So far, I have managed to switch the database on the Controller - but this means changing substantially the generated code - there must be an easier way! - Help!
Added comment:
The model is a SaaS accounting application. Each database stores all ledgers for a client company and has approximately 125 tables within it. They are kept separate for security and also portability (some accountants even require to download the SQL data in it's entirety for their clients).
Example code:
The site is built on the Contoso University model:
http://www.asp.net/mvc/tutorials/mvc-5/database-first-development/setting-up-database
It works in its basic form, but I need the connection changed for each clients data:
So looking at the Sales ledger - under the Sales controller we have:
public class SalesController : Controller
{
private Sales db = new Sales();
.....
The Sales definition is:
public partial class Sales : DbContext
{
public Sales()
: base("name=Sales")
{
}
The "name=Sales" links to the WebConfig and gives it the starting database.
Looking at the : base definition takes me to System.Data.Entity.DbContext which is a locked file!
I have trawled through various sites and tried putting the connection string in the Sales class the following being one of the suggestions:
public Sales(string connString) : base (connString)
but this throws:
Code generated using the T4 templates for Database First and Model First development may not work correctly if used in Code First mode. To continue using Database First or Model First ensure that the Entity Framework connection string is specified in the config file of executing application. To use these classes, that were from Database First or Model First, with Code First add any additional configuration using attributes or the DbModelBuilder API and then remove the code that throws this exception
Line 32: protected override void OnModelCreating(DbModelBuilder modelBuilder)
Line 33: {
Line 34: throw new UnintentionalCodeFirstException();
Line 35: }
Line 36:
That's where I am stuck - even if I use the same connection string as in the WebConfig!!
(It mentions Code First mode - which it wasn't?)
You could have your data access layer access an interface providing the connection string it uses? In the same way, if using EF, it might be a context rather than a connection string
public interface class IClient
{
string ConnectionString {get;set;}
}
public class DataAccess
{
private IClient _connectionString;
public DataAccess(IClient client)
{
_connectionString = client.ConnectionString;
}
}
This of course would change slightly based on your design. I would probably have the authentication for all clients on the same db, then based on who authenticates a factory could return an IClient which could then be used by DAL, Repository or whatever you have. IClient would not really just have a connection string or context, you could have other properties or methods on there too, relevant to requirements.
Internally, the Repository (for example) might use that context or connection string in the constructor, so it establishes the correct connection. Methods would not change.
Add a new parameterised Constructor as explained below.
In "Connectionstring" pass your connection like:
string Connectionstring="Data Source=;Initial Catalog=abc;Persist Security Info=True;
User ID=dsds;Password=dsdsd;MultipleActiveResultSets=True";
public Sales()
: base("name=Sales")
{
}
public Sales(string Connectionstring)
: base(Connectionstring)
{
}

Can't make EF Code First work with manually changed data base

I've added two new properties to my domain model class and two properties to a data table accordingly. Then I tried to launch my mvc web application and got
The model backing the 'EFDbContext' context has changed since the database was created.
Consider using Code First Migrations to update the database
(http://go.microsoft.com/fwlink/?LinkId=238269).
Having read the following posts:
MVC3 and Code First Migrations
EF 4.3 Automatic Migrations Walkthrough
I tried to Update-Database through Package Manager Console, but got an error
Get-Package : Не удается найти параметр, соответствующий имени параметра "ProjectName".
C:\Work\MVC\packages\EntityFramework.5.0.0\tools\EntityFramework.psm1:611 знак:40
+ $package = Get-Package -ProjectName <<<< $project.FullName | ?{ $_.Id -eq 'EntityFramework' }
+ CategoryInfo : InvalidArgument: (:) [Get-Package], ParameterBindingException
+ FullyQualifiedErrorId : NamedParameterNotFound,NuGet.PowerShell.Commands.GetPackageCommand
The EntityFramework package is not installed on project 'Domain'.
But the Entityframework is installed on project Domain. I removed it from references, deleted package.config and sucessfully reinstalled EF. But Update-Database still returns same error. Update-Database -Config does as well
What am I doing wrong?
EDIT
Many thanks to Ladislav Mrnka, I'll try to rephrase my question. As far as I changed my data table manually, I am not expected to use migration. But how can I now make EF work with manually edited domain model class and data table?
Try to add this to startup of your application (you can put it to App_Start):
Database.SetInitializer<EFDbContext>(null);
It should turn off all logic related to handling the database from EF. You will now be fully responsible for keeping your database in sync with your model.
I had the same problem and this is how I fixed the issue.
I dropped table __MigrationHistory using sql command and run the update-database -verbose again.
Apparently something was wrong with this automatic created table.
Answer 2 was exactly what was needed. Although when I got to the App_Start I realized that there were 4 configuration files and didn't see where this would fit in any of them. Instead I added it to my EF database context
namespace JobTrack.Concrete
{
public class EFDbContext : DbContext
{
//Set the entity framework database context to the connection name
//in the Webconfig file for our SQL Server data source QSJTDB1
public EFDbContext() : base("name=EFDbConnection")
{
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
//Remove the tight dependency on the entity framework that
//wants to take control of the database. EF by nature wants
//to drive the database so that the database changes conform
//to the model changes in the application. This will remove the
//control from the EF and leave the changes to the database admin
//side so that it continues to be in sync with the model.
Database.SetInitializer<EFDbContext>(null);
//Remove the default pluaralization of model names
//This will allow us to work with database table names that are singular
base.OnModelCreating(modelBuilder);
modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();
}
//Allows for multiple entries of the class State to be used with
//interface objects such as IQueryTables for the State database table
public DbSet<State> State { get; set; }
}
}

How to recreate database in EF if my model changes?

I created a DbContext like so :
public class myDB : DbContext
{
public DbSet<Party> Parties { get; set; }
public DbSet<Booking> Bookings { get; set; }
}
This generated my DataBase and the two tables above..Great
I then decided to add another DbSet into the mix & I got an error:
the model backing the 'Party' context has changed since the database was created
I'm aware of the fixes for this using modelbuilder.IncludeMetadataInDatabase = false; and Database.SetInitializer<ClubmansGuideDB>(null);
1) What's the correct way to add my new classes to the context and have them generated in the DataBase?
2) In my futile attempts to solve this myself I deleted the tables and tried to re-run the app with no success I then deleted the full database and re-run and it doesn't re-generate the DB. How can I start from scratch - is there some cache somewhere?
I believe you're looking for:
Database.SetInitializer<ClubmansGuideDB>(new DropCreateDatabaseIfModelChanges<ClubmansGuideDB>());
As of EF 4.1 and above.
Note that this assumes you have permission to even drop your database. I do this locally for ease of development but disable it in staging/production (I do a manual Schema Compare and push my changes).
By the way, for testing, if you need to force recreate the database, you can do:
using (var context = new ClubmansGuideDB()) {
context.Database.Initialize(force: true);
}
(using if you don't already have a reference to your DB)
You can let the Entity Framework recreate the whole database by using a Database Initializer or if you want to migrate data you can look at the Code First Migrations
The following would recreate your database when the model changes:
Database.SetInitializer<myDB>(new DropCreateDatabaseIfModelChanges<myDB>());
Try putting this in your Global.asax.cs Application_Start() method.
Database.SetInitializer<DatabaseContext>(null);
To reset the database from scratch on app run make a class like this
//Where myDB is your context
public class EntityBase: DropCreateDatabaseAlways<myDB>
{
}
Then in your Application_Start() method you can do this
Database.SetInitializer(new EntityBase());

Categories