【发布时间】:2021-02-09 15:38:25
【问题描述】:
请问ASP.Net core 中的Entity framework 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未配置特定的数据库提供程序。您可以通过覆盖OnConfiguring方法或在ConfigureServices类中的ConfigureServices方法中使用AddDbContext来配置它。异常消息也清楚地说明了如何解决问题。我很确定,在搜索该错误时,您应该能够自己找到解决方案。 -
请您在您的许可和非常感谢您的时间先生后提供一个解决方案作为答案
-
嗨@XDev,我的回答是否帮助您解决了您的问题?如果可以,请您接受作为答案吗?如果没有,请您跟进让我知道吗?参考:How to accept as answer .谢谢。
标签: c# asp.net-core entity-framework-core .net-5