I'm creating a web app that will allow users to log in to execute certain actions. I followed this tutorial (for simplicity, you can search for "Generate the database to store membership data" for the exact database setup I used).
Everything works fine in development, but when I deploy it and try to register a new user, it gives me the error:
An unhandled exception has occurred: SQLite Error 1: 'no such table: AspNetUsers'.
Is this because I need to do a 'dotnet ef database update' in deployment? If so, is there anyway I can avoid it, such that I can just deploy and have the database setup itself and be ready? The tutorial semi-talked about it by calling 'dbContext.Database.Migrate();', but I have no dbContext in the Configure() method... so I'm not sure how to fill in the gaps.
If there is any information about my code you'd like me to post, I'll be happy to post it for you. Thanks in advance!
I did happen to figure out how to fix the problem, but please bear with me on the details of the solution. It has been so long that I can only remember that Step 1 is definitely necessary, but I'm fairly fuzzy on if we also need to do Step 2. Some point down the line when I have time, I'll revisit this to confirm, but for now, I hope this will give you enough help to overcome the problem.
Step 1: Create your AspNetUsers table in your custom context class that inherits from IdentityDbContext<IdentityUser> with the following code. For the purposes of my example, I'm calling this class: CustomDbContext.
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.Entity<IdentityUser>().ToTable("AspNetUsers");
base.OnModelCreating(modelBuilder);
}
Note: If you aren't following the guide or using this for authentication, you'd simply have your custom context class inherit from DbContext.
Step 2: In your Startup.cs, you'll need to put the following code in your Startup() method, where you are literally ensuring that the CustomDbContext database (AspNetUsers) is created and available in production.
using (var client = new CustomDbContext())
{
client.Database.EnsureCreated();
}
Note: There is speculation that you could do client.Database.Migrate() in that using statement instead according to this (credit to Thomas Schneiter for letting me know), but I have not personally tried it to see if it works. There is another SO post relating to this particular piece of code with an answer I posted.
Related
After upgrading to Intershop CM 7.10.18.1, we are getting NullPtr exceptions while opening store detail page in backoffice.
ISML template for store details is EditStore_52.isml, which includes ISCountrySelectBox module, which futhermore calls getCountryNamesAndCodes() method.
That method fails with NullPtr exception because of underlined call which returns null.
We are wondering whether this is a bug and whether the intended code was supposed to be:
countriesMap.put(country.getId(), country.getDisplayName(currentLocale));
Please advise on workaround for this situation.
The following is a stack trace for exception.
Intershop delivers address data which can be imported/export through Operations backoffice (e.g. Login at https://localhost:8443/INTERSHOP/web/WFS/SLDSystem using Organization Operations). Out of the box such address data looks like this:
<country>
<id>DE</id>
<custom-attributes>
<custom-attribute dt:dt="string" name="displayName" xml:lang="de-DE">Deutschland</custom-attribute>
<custom-attribute dt:dt="string" name="displayName" xml:lang="fr-FR">Allemagne</custom-attribute>
<custom-attribute dt:dt="string" name="displayName" xml:lang="en-US">Germany</custom-attribute>
</custom-attributes>
</country>
As you can see, it only contains displayName attribute values for de-DE, fr-FR and en-US. A possible workaround in your case would be to export data, include missing attribute values and import it again.
Please note: The work to deliver a fix for this is already in progress. I'm sorry for the inconvenience.
The more convenient way (because editing xml import files is tedious) would be to replace the erroneous implementation using guice module override. In a nutshell:
Copy paste the original implementation of class com.intershop.component.region.internal.geoobject.LocalizedCountryNamesProviderImpl into a class of your own in your custom cartridge. For example: I just created a class AppSFLocalizedCountryNamesProviderImpl in cartridge app_sf_responsive to test this.
Adapt above method according to your needs
Create an override module (See Cookbook - Dependency Injection and ObjectGraphs). Following my example the modules configure operation should look like this:
#Override
protected void configure()
{
bind(LocalizedCountryNamesProvider.class).to(AppSFLocalizedCountryNamesProviderImpl.class);
bindProvider(com.intershop.component.foundation.capi.localization.LocalizedCountryNamesProvider.class)
.to(AppSFLocalizedCountryNamesProviderImpl.class);
}
Publish your cartridge, Restart your server
I am attempting to migrate from version 3.2.0 to 3.3.0. I am getting a compile error. I could not find an entry in the "Breaking Changes" section but here are my two errors in hope someone can guide me to a workable alternative.
public void RegisterTypeSingleton<T>(Type component, string name)
{
if (_container.Kernel.HasComponent(name))
_container.Kernel.RemoveComponent(name);
_container.Register(Component.For<T>().ImplementedBy(component).Named(name).LifeStyle.Singleton);
}
It seems Kernel.RemoveComponent() function has been depreciated. What has replaced this?
The second compiler error is at _container.Register(Component.For<T>().ImplementedBy(component).Named(name).LifeStyle.Singleton);
I am getting "The Type 'TService' must be a reference type in order to use it as a parameter.
I think you might be upgrading from an older version than 3.2.0. See below.
The removal of IKernel.RemoveComponent() is documented in the Breaking Changes document with v3.0.0. Here is the extract where Krzysztof explains why it was removed:
change - Removed the following methods:
GraphNode.RemoveDepender,
GraphNode.RemoveDependent,
IKernel.RemoveComponent,
IKernelEvents.ComponentUnregistered,
INamingSubSystem.this[Type service],
INamingSubSystem.GetHandler,
INamingSubSystem.GetService2Handler,
INamingSubSystem.GetKey2Handler,
INamingSubSystem.UnRegister(String key),
INamingSubSystem.UnRegister(Type service)
Also INamingSubSystem.Register now takes only IHandler as its argument
impact - low
fixability - none
description - The methods were implementation of "remove component from the container" feature
which was flawed and problematic, hecen was scraped.
fix - Working around is quite dependant on your specific usage. Try utilizing IHandlerSelectors.
For changed Register method, just update your calling code not to pass the name.
handler.ComponentModel.Name is now used as the key, as it was happening in all places so far
anyway, so this change should have no real impact.
RegisterComponent() won't overwrite an existing service registration, it'll just register another component for the same service, unless you specify the same name where it'll throw an exception informing you there is another component registered with that name. If your application doesn't replace components very often you could use the IsDefault() method on the registration to get Windsor to resolve the new component by default, just note the other component is still registered.
If your application replaces components often and you don't want the other registrations left there, you'd be best using a custom IHandlerSelector or ISubDependencyResolver so Windsor will ask you each time what component you want used for a specific service.
Also in v3.0.0 a change was made to ensure that value types cannot be passed to the registration methods. You'll need to add a generic constraint to your method that accepts a generic parameter so that it also only accepts reference types:
public void RegisterTypeSingleton<T>(Type component, string name)
where T : class
{
...
}
Folks,
I just started to design a new web project. From VS2012, I generated a new Internet website project. It comes with a database that is already laid out with a few tables. This is fine.
Now, I need to extend the database with a few new tables and update UserProfile with few new fields. However, as this is going to be a new database, I don't want to enable migration steps and add code-bloat that is not really needed.
Here is the workaround I found:
Extend UserProfile with new fields as you would want to.
Add new tables in AccountModels.cs. For example,
[Table("Items")]
public class Items {
...
}
For each new table, add a DbSet field to UsersContexts class in AccountModels.cs.
public class UserContext : DbContext {
...
public DbSet<Items> Items {get; set; }
}
Delete the original database file, create a new database file with the same name, and run the application.
Voila. The new database gets filled with all the tables.
Is this the right way to do it?
Although it works, I am not really sure about step 3. I figured somehow the framework needs to know that a new table needs to be created and essentially adding a new field to UserContext triggers the creation of the new table. Is this the approach right?
Thank you in advance for your help.
Regards,
Peter
By not using code first migrations, deleting the database manually is the best thing you can do. There is also the DropCreateDatabaseIfModelChanges initializer but be careful to never use it in a release version of your app.
I would also recommend to write the DbContext in a seperate cs file. When you use the fluent api to configure the EF relations (what i would do), it can get really big. Think about putting the DAL and your models in seperate projects when your solution gets bigger. Using multiple contexts for one db can also cause problems, so naming it SomeAppContext would be better.
I am in the begining of making a simple website using ASP.NET MVC4 CodeFirst Approach. The web site is built around users who are able to register, make posts etc. The existing UserProfile class was modified for the accommodation other fields (ex: FirstName, LastName etc).
When I ran the website I got a similar error:
Invalid column name 'FirstName'.
Invalid column name 'LastName'.
Invalid column name 'Phone'.
I red that this is because the Database is not updated as the model is updated. So I set the following on the Application_Start() in Global.asax with the intention of droppnng the database always (at least until I get the hang of it).
protected void Application_Start()
{
Database.SetInitializer(new DropCreateDatabaseAlways<UsersContext>());
//Other default generated stuff below...
}
I also tryed the DropCreateDatabaseIfModelChanges, but both methods didn't drop the database.
Isn't this possible? Why is it? Am I doing some thing wrong?
I believe it would be possible to store the info in a different table and link it to this, but I prefer to keep it in one table.
Also is it a bad idea to add UserProfiles to the websites context (lets say: DatabaseContext (which has other entities like Posts, Comments etc) and change the AccountsController to use DatabaseContext instead of UsersContext?
Thanks in advance.
Have you run Enable-Migrations in the Package Manager Console? You should see a migration folder in your project, with a configuration.cs file, ensure you have enabled automatic migrations.
public Configuration(){
AutomaticMigrationsEnabled = true;
//if you drop columns - consider this carefully...
AutomaticMigrationDataLossAllowed = true;
}
I use EF Code First in my solution with SQL Server Express behind it. When I update my model, I always have to delete my database before restarting my solution. I know this is because my database is no more up to date. In that case, I lose all data in my tables.
I would like to be able to update my models (for example: adding a new field) and keeping all data in my tables.
Even if I update manually my database, when I restart the solution, I get the error below:
The model backing the 'EntityFrameworkDbContext' context has changed since the database was created. Either manually delete/update the database, or call Database.SetInitializer with an IDatabaseInitializer instance
Any suggestions?
Thanks.
You can remove the creation of EdmMetadata table as follows.
public class MyContext : DbContext
{
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Conventions.Remove<IncludeMetadataConvention>();
}
}
This way you can manually update the database without getting the error.
You can check out Code First Migrations
To expand a bit on my comment. This is not generally possible, nor was CF designed for this. The only way around is to manually update your tables with SQL commands AND to update the database model verification hash stored as EDMmetadata or some such in your database, before you live an update your Code first model.
To get the proper hash value you can create a temporary database and just copy your value from there.
Not pretty, but it works.