C#程序調試錯誤集
1.依賴注入錯誤System.InvalidOperationException: Unable to resolve service for type 'xxx' while attempting to activate 'xxx'.
1.1 出錯現象
System.InvalidOperationException: Unable to resolve service for type 'IBMS.Infrastruct.UoW.UnitOfWork' while attempting to activate 'IBMS.WEBAPI.Controllers.ValueController'.
出錯圖片如下:
1.1.1原因是net core在調用ValueController的時候,發現UnitOfWork沒有進行依賴注入。
1.2 出錯現象
System.InvalidOperationException: Unable to resolve service for type 'IBMS.Infrastruct.Context.IPBoxContext' while attempting to activate 'IBMS.Infrastruct.UoW.UnitOfWork'.
出錯圖片如下:
1.2.1 原因是net core在調用UnitOfWork的時候,發現IPBoxContext沒有進行依賴注入。
1.3 解決方法
在startup.cs中的ConfigureServices方法中進行依賴注入
services.AddDbContext<IIPBoxContext, IPBoxContext>(options =>
options.UseMySql(Configuration.GetConnectionString("MySqlConnection")));
services.AddScoped<IIPBoxRepository, IPBoxRepository>();
services.AddScoped(typeof(UnitOfWork));//注入工作單元
services.AddScoped(typeof(IPBoxContext));
注意:IPBoxContext進行AddDbContext注入數據上下文之后,仍需要注入services.AddScoped(typeof(IPBoxContext))。
2. 未創建實例錯誤
2.1 出錯現象Object reference not set to an instance of an object.
出錯圖片如下:
2.1.1 原因是沒有創建數據庫上下文對象
2.2 出錯現象System.ArgumentNullException: Value cannot be null.
出錯圖片如下:
2.2.1 原因是沒有創建數據庫上下文對象
2.3 解決方法
在服務層創建一個實例的倉儲,並傳入其對應的數據上下文。
public class IPBoxServices : ServicesBase<IPBox>, IIPBoxServices
{
public IPBoxContext DbContext { get; set; } = null;
public IPBoxServices(IPBoxContext dbContext)
{
DbContext = dbContext;
}
#region 字段
private IPBoxRepository _IPBoxRepository = null;
#endregion
#region 操作類屬性
public IPBoxRepository IPBoxRepository => _IPBoxRepository ?? (_IPBoxRepository = new IPBoxRepository(DbContext));
#endregion
}
備注:這里最好是在RepositoryBase里直接通過數據庫工廠模式創建一個數據庫的上下文,這樣不會讓倉儲層泄露到應用層。當然以上方法基本沒什么很大影響。
3.傳入EF Core 拉姆達(lambda)表達式為空報錯
3.1 出錯現象
System.ArgumentNullException: Value cannot be null. at lambda_method(Closure , Object , Object[] )
出錯圖片如下
3.1.1 原因
獲取列表數據時傳入lambda表達式為空。具體如下。
AlarmList = _alarmServices.GetList();
3.2解決方法
當lambda表達式為空時,直接返回列表數據。問題得到有效解決
if (predicate == null)
{
return _dbSet.ToList();
}
整個代碼塊如下:
public List<TEntity> GetList(Expression<Func<TEntity, bool>> predicate = null, string ordering = "", bool isNoTracking = true)
{
if (predicate == null)
{
return _dbSet.ToList();
}
var data = isNoTracking ? _dbSet.Where(predicate).AsNoTracking() : _dbSet.Where(predicate);
if (!string.IsNullOrEmpty(ordering))
{
data = data.OrderByBatch(ordering);
}
return data.ToList();
}
4.泛型類約束出錯
4.1 什么是泛型類約束
where TEntity : class
表示TEntity必須是一個類。
4.2 出錯現象
錯誤 CS0311 類型“TEntity”不能用作泛型類型或方法“DbContextExtensions.UpdatePerfect
4.2.1 解釋
倉儲層的TEntity不能用做擴展層的TEntity。因為一個是需要包含IEntity,而一個是沒有包含
4.3 出錯原因
實際的Entity調用中用了IEntity字段,但是倉儲層中沒有包含IEntity。
4.4 解決
倉儲層包含IEntity的泛型約束即可。
where TEntity : class,IEntity
問題得到圓滿解決。
5.無法將'System.Boolean'類型轉化到 'System.SByte'類型
5.1 錯誤提示
System.InvalidCastException: Unable to cast object of type 'System.Boolean' to type 'System.SByte'.
5.2 錯誤原因
數據庫mysql設置了tinyint(1)類型(mysql會自動將其轉化成bool類型),而C#中是byte類型。導致bool與byte (tinyint)之間無法轉化。
5.3 解決方法
在mysql連接字符串中加入TreatTinyAsBoolean=false;這樣,mysql不會將tinyint轉化成bool類型。即可解決問題
6.log4Net已經沒法滿足Net Core 3.1了,可以生成包,但是依賴過低了,無法打包發布。智能能夠生成VS工具里面運行。
6.1 錯誤提示
6.2 錯誤原因
依賴包過低,該插件也沒在維護。
6.3 解決方法
換用Nlog。