Database Table Export to CSV using EntityFramework DbContext .NET 6
I have been tasked to create a Blazor ASP.NET Core application that will export each table from an MS SQL Server database into it's own .csv
file. I have extracted the DbSets
from the DbContext
properties into a generic list, but when I attempt to cast the generic objects to their DbSet
class I get the following error:
An unhandled exception occurred while processing the request. MissingMethodException: Constructor on type 'Microsoft.EntityFrameworkCore.DbSet`1[[DatabaseTableExport.Data.LoginDbModels.AccountPasswordHistory, DatabaseTableExport, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]]' not found. System.RuntimeType.CreateInstanceImpl(BindingFlags bindingAttr, Binder binder, object[] args, CultureInfo culture)
How do I fix this error, or is there a better way to be extracting the DbSets
from the DbContext
?
using DatabaseTableExport.Data;
using DatabaseTableExport.Data.LoginDbModels;
using Microsoft.AspNetCore.Components;
using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
namespace DatabaseTableExport.Pages
{
public partial class Index : ComponentBase
{
[Inject]
private LoginDbContext LoginDbContext { get; set; }
[Inject]
private ApplicationDbContext ApplicationDbContext { get; set; }
protected override void OnInitialized()
{
List<DbSet<object>> dbSets = GetDbSets(LoginDbContext);
// iterate through each DbSet instance
foreach (var dbSet in dbSets)
{
// export to csv here
}
}
private static List<DbSet<object>> GetDbSets(DbContext loginDbContext)
{
// Retrieve all the DbSet properties declared on the context class.
var dbSetProperties = loginDbContext.GetType()
.GetProperties(BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly)
.Where(p => p.PropertyType.IsGenericType && p.PropertyType.GetGenericTypeDefinition() == typeof(DbSet<>))
.ToList();
// Iterate over each DbSet property and add it to the list of dbsets.
var dbSets = new List<DbSet<object>>();
foreach (var property in dbSetProperties)
{
// If the type of the DbSet is null, skip it.
if (property.PropertyType.GenericTypeArguments.Length <= 0)
{
continue;
}
// Get the generic type arguments and create a corresponding DbSet instance.
var dbsetGenericType = property.PropertyType.GenericTypeArguments[0];
var convertedDbSet = Activator.CreateInstance(typeof(DbSet<>).MakeGenericType(dbsetGenericType), property.GetValue(loginDbContext));
dbSets.Add((DbSet<object>)convertedDbSet);
}
// Return the list of DbSet objects.
return dbSets;
}
}
}
GetDbSets
has no sense without explanation. – GravidGetDbSets
is defined and included with the code above. It is the method that gets theDbSets
and returns them so they can be used to export the data to a.csv
file. – Stroller