DbModelBuilder/ModelBuilder .NetCore OnModelCreating and Execute raw sql - c#

In .net, we had DBContext class with overriding DbContext method
OnModelCreating
DbModelBuilder.Conventions.Remove
DbModelBuilder.Conventions.Add
This is not available in .net 6 ModelBuilder. How can we achieve this?
Also Database.ExecuteSqlCommand(sqlcommand, params) or ExecuteSqlCommandAsync is not available
FYI: Microsoft.EntityFrameworkCore 7.0.2 is being used

Related

.Net 6 EF Core DbContext and Models In Separate Class Libary

I have a solution with the following projects:
ASP.NET Core MVC website
ASP.NET Core Web API
DAL [incl DbContext and model classes]
Both the website and API reference the DAL and can use it's dbContext and model classes.
Both these projects have an appsettings.json file with the connection string and DB access is all working.
I can't how ever work out how to add migrations.
If I set the default project to the DAL project, I get this error:
Unable to create an object of type 'myDbContext'. For the different patterns supported at design time, see https://go.microsoft.com/fwlink/?linkid=851728
If I set it to the Api or website, I get:
Your target project 'website' doesn't match your migrations assembly 'DAL'. Either change your target project or change your migrations assembly.
Change your migrations assembly by using DbContextOptionsBuilder. E.g. options.UseSqlServer(connection, b => b.MigrationsAssembly("website")). By default, the migrations assembly is the assembly containing the DbContext.
Change your target project to the migrations project by using the Package Manager Console's Default project drop-down list, or by executing "dotnet ef" from the directory containing the migrations project.
I can find information on how to set up a separate class lib for the dbcontect and models for .NET Core 3.1 but I am struggling with .NET 6.
I have tried to follow this tutorial
https://garywoodfine.com/using-ef-core-in-a-separate-class-library-project/
But it's not the same as .net 6 so I cant follow it as I get errors when I try and create the DBContextFactory towards the bottom. The SetBasePath is not a definition within ConfigurationBuilder. I'm not fluent enough with .NET Core to work out whats required.
I have the exact same setup as you have with a website, api and a DAL layer.
This is how I register the DbContext in the website and in the api program.cs:
builder.Services.AddDbContext<AppDbContext>(
options => options.UseSqlServer(config.ConnectionString, sqlOptions => {
sqlOptions.MigrationsAssembly("App.Entities");}));
This is how the AppDbContext is created in the DAL project:
public class AppDbContext : DbContext
{
public AppDbContext(DbContextOptions<AppDbContext> options) : base(options)
{ }
// Your DbSet entities here
}
Then when you run your first migration command "Add-Migration" you need to select the DAL project in the package manager console dropdown and it should automatically create the migration folder with the migration files.
You need to have the following packages installed in the DAL project:
Microsoft.EntityFrameworkCore.SqlServer
Microsoft.EntityFrameworkCore.Tools
Honestly, one would need more information to narrow down the problem.
I think there are two possible problems.
You are not using the exact DB Context in the program.cs of the two project in the presentation layer(MVC and API).
You have updated the migration the migration on API or MVC, or you have made changes to the database hence the comparison is not as clear.
How to resolve:
Make sure that database connection string in the two application.json
is same
Make sure that in the Program.cs of the the API and the MVC, that you have added the exact dbcontext from DAL "and is identical".
Make sure you have uniform Nugget package across the solution for the EF tool, Server, Design
Make sure the Models in the last migration mirrors what is obtainable in the database.
Make sure that the Package Manager console is has DAL selected as the default project, while the startup project which can be MVC or API is not having any errors.
Make sure that there is a dbSet<> in the dbContext in DAL before adding a migration

How to resolve EF Core context with Unity container in a .net 4.7 project

I have an issue where I need to upgrade my projects to the latest version of .NET, currently all projects are .NET 4.7 or .NET Standard 2.0 using Entity Framework 6 this is then exposed through a WCF service which gets its instantiations via Unity.
The plan was to start with an upgrade from EF 6 to EF Core 3 and then also decouple it using Inversion of control to be able to change the underlying data access if needed, this has been started with all repository calls reference the interface IMyDbContext and seems to be okay.
Now i have an issue of how to resolve IMyDbContext from the Unity container in the WCF app given that it is .Net 4.7 and the project containing MyDbContext is .net core 3.
Any pointers/references would be greatly appreciated.
For a solution with multiple projects, some on .Net Framework and some on .Net Core I use something like this:
public class MyContext : DbContext
{
static MyContext()
{
Database.SetInitializer<MyContext>(null);
}
[InjectionConstructor] //Used to specify the constructor to Unity
public MyContext()
: base("Name=MyContext")
{
}
public MyContext(string connectionString) //Used to resolve de dependency in .net Core
: base(connectionString)
{
}
}
Startup.cs in .Net Core MVC project
public void ConfigureServices(IServiceCollection services)
{
services.AddControllersWithViews();
services.AddScoped<MyContext>(_ => new MyContext(Configuration.GetConnectionString("DefaultConnection")));
}
And in the .Net Framework project is passed as a parameter to a repository, IDoStuffRepo, which is registered like this:
public override void Initialize(){
this.Container.RegisterType<IDoStuffRepo, DoStuffRepo>(new DisposableTransientLifetimeManager());
}

Cannot see the DbContext from another project in asp.net core

I have a web api project "Reactivities" and another project "Persisitence" to place my DbContext. When I try to use my add-migration in the Reactivities, using this syntax in the console add-migration InitalCreate -Context .\Persistence I get this error:
No DbContext named '.\Persistence' was found.
Even if I use add-migration InitialCreate -Context .\Persistence\DataContext still I get the same error,
This is in my startup class in Reactivities
services.AddDbContext<DataContext>(opt =>
{
opt.UseSqlite(Configuration.GetConnectionString("DefaultConnection"));
});
How can I correct this?
You have to do migration work in a project that instantiates the dbcontext, in my case I have created a dbmigrator project with a class that inherits the
IDesignTimeDbContextFactory<T>
where T is the dbcontext type.
This allows me to have a project that has the dbcontexts, a project that works with migrations and a project that uses the dbcontexts independently of each other.
This guide shows you how to use the interface i mentioned:
https://codingblast.com/entityframework-core-idesigntimedbcontextfactory/

Entity Framework 6 vs Entity Framework Core - subtle differences?

I am writing a .NET Framework WPF application and I use Entity Framework. At first I installed the EF Core package and when doing my first add-migration I received the famous error
Unable to create an object of type 'DbContext'. For the different patterns supported at design time, see https://go.microsoft.com/fwlink/?linkid=851728
However, this is not what my question is about. I knew I got it to work sometime before and I noticed that that was when I used EF 6 instead of EF Core. So I uninstalled the EF Core packages and installed EF 6 package instead. And now with EF 6 migrating works just fine, which is great.
But my question is: why IS it working? Even though I did not change my code by adding an IDesignTimeFactory<DbContext> or dependency injection for instantiation of my DbContext class. Yet it still works just by switching back to EF 6. I couldn't find any information on differences between the two (i.e. EF Core and EF 6) that would explain this. So now I'm hoping someone here can enlighten me with their vast knowledge.
For reference, here is my DbContext class:
public class PinboardContext : DbContext
{
public PinboardContext() : base()
{
}
public DbSet<Item> Items { get; set; }
}
My App.xaml.cs class is empty apart from an empty constructor.
Lastly, if that is of importance, I have a connectionString defined in app.config as follows:
<connectionStrings>
<add name="mpcn" connectionString="Data Source=(localdb)\MSSQLLocalDB; Initial Catalog=MyPinboardDB;Integrated Security=True;" providerName="System.Data.SqlClient"/>
</connectionStrings>
Note that I have already looked at this but it didn't help me answer my question.
Probably because you have to pass a DbContextOptions<PinboardContext> to your DbContext base class.
If no options are provided, EF6 uses a connection string from the config file with the name of the derived DbContext, or failing that assumes a database with the name of the derived DbContext on the default database installation.
EF Core requires that options must be provided.
It is not a requirement in EF Core that the DbContext is created by injection. If it is created by injection, it must be configured with the appropriate DbContextOptions<T>. If created directly, the DbContextOptions<T> must be provided directly.

AutoMapper in ASP.Net Core 2.0

Does someone know if there's any way to use AutoMapper with ASP.Net Core 2.0?
There's no extension for IServiceCollection.
And optional question, does anyone tryed to work with AutoMapper with .Net Framework 4.7 or .Net Standard 2.0?
It turns out you need to add both:
- AutoMapper
- AutoMapper.Extensions.Microsoft.DependencyInjection
or only the 2nd one (which have dependency to the 1st one).
You can create an AutoMapperProfile.cs then add to startup.cs like code below
public class AutoMapperProfile : Profile
{
public AutoMapperProfile()
{
CreateMap<Abc, AbcEntity>();
}
}
Add to ConfigureServices method in startup.cs
//Automapper profile
Mapper.Initialize(cfg => cfg.AddProfile<AutoMapperProfile>());
As mentioned above you need the AutoMapper, and AutoMapper.Extensions.Microsoft.DependencyInjection Nuget packages.
Then in your Startup ConfigureServices method if you just add the service using:
services.AddAutoMapper();
This will scan all assemblies within the execution context looking for classes that inherit the Automapper.Profile class and automatically add these to the AutoMapper configuration.

Categories