Пожалуйста, у меня проблема с 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; }
}
Code First 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
не настроен с конкретным поставщиком БД. Вы можете настроить его, переопределив методOnConfiguring
или используяAddDbContext
вConfigureServices
методе в классеStartup
. Сообщение об исключении также четко объясняет, как можно решить проблему. Я почти уверен, что при поиске этой ошибки в Google вы должны были найти решение самостоятельно. - person King King   schedule 07.02.2021