Моля, имам проблем с Entity framework core
в ASP.Net core
. Първо, аз съм аматьор както в EF Core
, така и в ASP.Net Core
.
Идея:
Опитвам се да създам генерично хранилище, за да правя някои повтарящи се процедури, без да повтарям кода, когато работя с множество контексти.
Класът Repo:
public sealed class Repo<TContext> : IRepo<TContext>, IDisposable where TContext : DbContext, new()
{
#region properties
/// <summary>
/// Private DBContext property
/// </summary>
private DbContext _Context { get; } = null;
/// <summary>
/// Determine if Lazy Loading either activate or not
/// </summary>
private bool _LazyLoaded { get; set; }
#endregion
#region Construcors
public Repo(bool LazyLoaded)
{
_Context = new TContext();
_LazyLoaded = LazyLoaded;
_Context.ChangeTracker.LazyLoadingEnabled = LazyLoaded;
}
#endregion
#region Routines
#region Select
/// <summary>
/// Get All records from a table
/// </summary>
/// <typeparam name="TEntity">The entity to select from</typeparam>
/// <returns></returns>
public IEnumerable<TEntity> GetAll<TEntity>() where TEntity : class
{
return _Context.Set<TEntity>().ToList();
}
/// <summary>
/// Asynchronously, Get All records from a table
/// </summary>
/// <typeparam name="TEntity">The entity to select from</typeparam>
/// <returns></returns>
public Task<IEnumerable<TEntity>> GetAllAsync<TEntity>() where TEntity : class
{
return Task.Factory.StartNew(() => GetAll<TEntity>());
}
/// <summary>
/// Get One record from a table, based on the primary key value
/// </summary>
/// <typeparam name="TEntity">The entity to select from</typeparam>
/// <param name="pkValue">The primary key value</param>
/// <returns></returns>
public TEntity GetOne<TEntity>(object pkValue) where TEntity : class
{
return _Context.Set<TEntity>().Find(pkValue);
}
/// <summary>
/// Asynchronously, Get One record from a table, based on the primary key value
/// </summary>
/// <typeparam name="TEntity">The entity to select from</typeparam>
/// <param name="pkValue">The primary key value</param>
/// <returns></returns>
public Task<TEntity> GetOneAsync<TEntity>(object pkValue) where TEntity : class
{
return Task.Factory.StartNew(() => GetOne<TEntity>(pkValue));
}
#region Preview feature
/// <summary>
/// Get Many records from a table based on a property value
/// </summary>
/// <typeparam name="TEntity">The entity to select from</typeparam>
/// <param name="prop">The property used in the condition</param>
/// <param name="val">The value that will used in the search</param>
/// <returns></returns>
public IEnumerable<TEntity> GetMany<TEntity>(string prop, object val) where TEntity : class
{
return _Context.Set<TEntity>().AsEnumerable()
.Where(x => typeof(TEntity).GetProperty(prop).GetValue(x, null).ToString()
.Contains(val.ToString())).ToList();
}
#endregion
#endregion
#region Contains
/// <summary>
/// Check if a entity contains an object
/// </summary>
/// <typeparam name="TEntity">Entity to be look in</typeparam>
/// <param name="obj">The object to be looking for</param>
/// <returns></returns>
public bool Contains<TEntity>(TEntity obj) where TEntity : class
{
return _Context.Set<TEntity>().AsEnumerable().Contains(obj);
}
/// <summary>
/// Asynchronously Check if a entity contains an object
/// </summary>
/// <typeparam name="TEntity">Entity to be look in</typeparam>
/// <param name="obj">The object to be looking for</param>
/// <returns></returns>
public Task<bool> ContainsAsync<TEntity>(TEntity obj) where TEntity : class
{
return Task.Factory.StartNew(() => Contains<TEntity>(obj));
}
/// <summary>
/// Check if a entity contains an object based on a custom EQUALITY Comparer
/// </summary>
/// <typeparam name="TEntity">Entity to be look in</typeparam>
/// <typeparam name="TEntityComparer">The custom TEntity EQUALITY Comparer</typeparam>
/// <param name="obj">The object to be looking for</param>
/// <returns></returns>
public bool Contains<TEntity, TEntityComparer>(TEntity obj)
where TEntity : class
where TEntityComparer : IEqualityComparer<TEntity>, new()
{
return _Context.Set<TEntity>().AsEnumerable().Contains(obj,new TEntityComparer() as IEqualityComparer<TEntity>);
}
/// <summary>
/// Asynchronously Check if a entity contains an object based on a custom EQUALITY Comparer
/// </summary>
/// <typeparam name="TEntity">Entity to be look in</typeparam>
/// <typeparam name="TEntityComparer">The custom TEntity EQUALITY Comparer</typeparam>
/// <param name="obj">The object to be looking for</param>
/// <returns></returns>
public Task<bool> ContainsAsync<TEntity, TEntityComparer>(TEntity obj)
where TEntity : class
where TEntityComparer : IEqualityComparer<TEntity>, new()
{
return Task.Factory.StartNew(() => Contains<TEntity, TEntityComparer>(obj));
}
#endregion
#region Insert
/// <summary>
/// Insert one record into the database table
/// </summary>
/// <typeparam name="TEntity">Entity to add into</typeparam>
/// <param name="record">The record to be added</param>
public void Insert<TEntity>(TEntity record) where TEntity : class
{
_Context.Set<TEntity>().Add(record);
}
/// <summary>
/// Asynchronously, Insert one record into the database table
/// </summary>
/// <typeparam name="TEntity">Entity to add into</typeparam>
/// <param name="record">The record to be added</param>
public Task InsertAsync<TEntity>(TEntity record) where TEntity : class
{
return Task.Factory.StartNew(() => Insert(record));
}
/// <summary>
/// Insert a range of reords in a table
/// </summary>
/// <typeparam name="TEntity">Entity to insert into</typeparam>
/// <param name="records">Records to be inserted</param>
public void InsertRange<TEntity>(List<TEntity> records) where TEntity : class
{
_Context.Set<TEntity>().AddRange(records);
}
/// <summary>
/// Asynchronously, Insert a range of reords in a table
/// </summary>
/// <typeparam name="TEntity">Entity to insert into</typeparam>
/// <param name="records">Records to be inserted</param>
public Task InsertRangeAsync<TEntity>(List<TEntity> records) where TEntity : class
{
return Task.Factory.StartNew(() => InsertRange(records));
}
#endregion
#region Delete
/// <summary>
/// Delete One record from a database table
/// </summary>
/// <typeparam name="TEntity">Entity to remove from</typeparam>
/// <param name="record">The record to be removed</param>
public void Delete<TEntity>(TEntity record) where TEntity : class
{
this._Context.Set<TEntity>().Remove(record);
}
/// <summary>
/// Asynchronously, Delete One record from a database table
/// </summary>
/// <typeparam name="TEntity">Entity to remove from</typeparam>
/// <param name="record">The record to be removed</param>
public Task DeleteAsync<TEntity>(TEntity record) where TEntity : class
{
return Task.Factory.StartNew(() => Delete(record));
}
#endregion
/// <summary>
/// Save the repository changes
/// </summary>
public void Save()
{
_Context.SaveChanges();
}
#endregion
#region Disposing
#region Properties
private bool _disposed { get; set; } = false;
#endregion
private void Dispose(bool disposing)
{
if (!_disposed)
{
if (disposing)
{
_Context.Dispose();
}
}
_disposed = true;
}
public void Dispose()
{
this.Dispose(true);
GC.SuppressFinalize(this);
}
#endregion
}
В ядрото на ASP.Net:
Models
public class Client
{
[Key]
public string ID { get; set; }
public string Name { get; set; }
public int Age { get; set; }
public virtual ICollection<Order> Orders { get; set; }
}
public class Order
{
[Key]
public int ID { get; set; }
public Client CLT { get; set; }
public string PRD { get; set; }
public decimal Total { get; set; }
}
Кодирайте първия DbContext:
public class TrainContext:DbContext
{
public TrainContext(DbContextOptions<TrainContext> contextOptions) : base(contextOptions)
{
}
public TrainContext()
{
}
protected void OnModelCreating(ModelBuilder builder)
{
foreach (var property in builder.Model.GetEntityTypes().SelectMany(t => t.GetProperties()).Where(p => p.ClrType == typeof(decimal) || p.ClrType == typeof(decimal?)))
{
property.SetColumnType("decimal(18,2)");
}
}
#region DB Sets
public virtual DbSet<Client> Client { get; set; }
public virtual DbSet<Order> Order { get; set; }
#endregion
}
Client
Контролер:
public class ClientController : Controller
{
private readonly Repo<TrainContext> db = new Repo<TrainContext>(false);
private readonly TrainContext _context;
public ClientController(TrainContext context)
{
_context = context;
}
public IActionResult Index()
{
//var data = _context.GetAll<Models.Client>();
var data = _context.Client.ToList();
ViewBag.Clients = data;
return View();
}
}
Метод Startup.cs ConfigureServices
:
public void ConfigureServices(IServiceCollection services)
{
services.AddControllersWithViews();
services.AddDbContext<TrainContext>(options => options.UseSqlServer(Configuration.GetConnectionString("DB")));
}
AppSettings.Json:
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"AllowedHosts": "*",
"ConnectionStrings": {
"DB": "Server=ServerName; Database=GOrders;Integrated Security=True"
}
}
Проблемът:
Проблемът е, че това хранилище работи добре, когато предам Db First Context
в Конзолно приложение.
Но когато се опитам да използвам това хранилище в моето Asp.Net core
приложение с Code first
подход, получих тази грешка:
InvalidOperationException: No database provider has been configured for this DbContext. A provider can be configured by overriding the 'DbContext.OnConfiguring' method or by using 'AddDbContext' on the application service provider. If 'AddDbContext' is used, then also ensure that your DbContext type accepts a DbContextOptions<TContext> object in its constructor and passes it to the base constructor for DbContext.
Моля за помощ за отстраняването на този проблем? и огромни благодарности предварително.
DbContext
не е конфигуриран с конкретен доставчик на db. Можете да го конфигурирате, като замените методаOnConfiguring
или използватеAddDbContext
вConfigureServices
метод вStartup
клас. Съобщението за изключение ясно обяснява как можете да разрешите проблема. Почти съм сигурен, че когато търсите в Google за тази грешка, трябва да сте успели да намерите решението сами. - person King King   schedule 07.02.2021