昨天EF莫名其妙的,掉所有接口訪問都出現如下錯誤:百度,Google了半天,倒是有很多人都遇到了這個問題,但都沒有一個解決方案,或者解決方案無效。通過層層排除,終於找到問題的所在。記錄下來,給以后再遇到此問題的朋友們節省一些找問題的時間。而且這錯誤的原因如果不細心還真不好找。
異常信息如下:
{"Message":"出現錯誤。","ExceptionMessage":"值不能為 null。\r\n參數名: entitySet","ExceptionType":"System.ArgumentNullException","StackTrace":" 在 System.Data.Entity.Utilities.Check.NotNull[T](T value, String parameterName)\r\n 在 System.Data.Entity.Core.Mapping.EntitySetMapping..ctor(EntitySet entitySet, EntityContainerMapping containerMapping)\r\n 在 System.Data.Entity.ModelConfiguration.Edm.DbDatabaseMappingExtensions.AddEntitySetMapping(DbDatabaseMapping databaseMapping, EntitySet entitySet)\r\n 在 System.Data.Entity.ModelConfiguration.Edm.Services.TableMappingGenerator.Generate(EntityType entityType, DbDatabaseMapping databaseMapping)\r\n 在 System.Data.Entity.ModelConfiguration.Edm.Services.DatabaseMappingGenerator.GenerateEntityTypes(DbDatabaseMapping databaseMapping)\r\n 在 System.Data.Entity.ModelConfiguration.Edm.Services.DatabaseMappingGenerator.Generate(EdmModel conceptualModel)\r\n 在 System.Data.Entity.ModelConfiguration.Edm.EdmModelExtensions.GenerateDatabaseMapping(EdmModel model, DbProviderInfo providerInfo, DbProviderManifest providerManifest)\r\n 在 System.Data.Entity.DbModelBuilder.Build(DbProviderManifest providerManifest, DbProviderInfo providerInfo)\r\n 在 System.Data.Entity.DbModelBuilder.Build(DbConnection providerConnection)\r\n 在 System.Data.Entity.Internal.LazyInternalContext.CreateModel(LazyInternalContext internalContext)\r\n 在 System.Data.Entity.Internal.RetryLazy`2.GetValue(TInput input)\r\n 在 System.Data.Entity.Internal.LazyInternalContext.InitializeContext()\r\n 在 System.Data.Entity.Internal.InternalContext.Initialize()\r\n 在 System.Data.Entity.Internal.InternalContext.GetEntitySetAndBaseTypeForType(Type entityType)\r\n 在 System.Data.Entity.Internal.Linq.InternalSet`1.Initialize()\r\n 在 System.Data.Entity.Internal.Linq.InternalSet`1.get_InternalContext()\r\n 在 System.Data.Entity.Infrastructure.DbQuery`1.System.Linq.IQueryable.get_Provider()\r\n 在 System.Data.Entity.QueryableExtensions.SingleOrDefaultAsync[TSource](IQueryable`1 source, Expression`1 predicate, CancellationToken cancellationToken)\r\n 在 System.Data.Entity.QueryableExtensions.SingleOrDefaultAsync[TSource](IQueryable`1 source, Expression`1 predicate)\r\n 在 BellChat.Business.UserService.<Login>d__4.MoveNext()
值不能為 null。參數名: entitySet。 表明是因為DBmodel 和數據庫表格映射過程出現的問題,可以從model和表字段對應不上,或者數據庫字段類型EF無法識別,這兩點着手尋找錯誤的根源。
我這邊最后找到的原因如下:
我有一處Include代碼:
var result = db.Conversations.Where(m => (m.UserId == user.Id || m.TargetUserId == user.Id) && m.Id > req.Begin)
.Include(m => m.TargetUser).Include(m => m.LastMsg).Take(req.Count);
其中的TargetUser對象並不是對應數據庫中的user表DBModel,而是一個自定義的responseModel。導致EF的Include失敗,而這種錯誤完全不影響編譯,調試時也無法定位到Include(m => m.TargetUser)這句代碼,且該錯誤不僅僅只影響這一處接口調用的結果,它會導致整個EF數據庫操作都報錯,讓你摸不着頭腦。就感覺是EF在系統啟動的時候先閱讀整個程序代碼,提前映射所有model,只要有一個model映射不上,整個EF就不能用。
解決辦法如下:
將.Include(m => m.TargetUser)中的TargetUser改成數據庫model就好了
public partial class Conversation
{
[JsonIgnore]
public User TargetUser { get; set; } //原來是public SeekerSimple TargetUser { get; set; }
public Message LastMsg { get; set; }
}
