EF查询抛出System.ArgumentNullException(queryString)问题求助
System.ArgumentNullException: Value cannot be null. Parameter name: queryString异常 我来帮你分析这个问题的原因和解决办法:
异常原因分析
这个异常通常出现在EF尝试构建SQL查询时失败,导致生成的queryString为空。结合你的代码和禁用延迟加载的情况,主要问题有两个:
多余的
Include语句与投影冲突:你在查询中使用了Include(p => p.Sites.Select(q => q.Buildings)),但紧接着又在Select投影中对Sites和Buildings进行了过滤和DTO转换。Include是用来加载完整的实体关联数据的,而投影操作是生成自定义DTO结构,两者混合会让EF的查询解析器混乱,无法正确生成有效的SQL查询。投影中使用
IEnumerable导致的查询生成问题:你的DTO(SiteSlimDao、BuildingSlimDao)中CustomFields定义为IEnumerable<string>,在禁用延迟加载的情况下,EF无法正确处理这种类型的投影,会尝试生成无效的查询逻辑,进而引发空queryString异常。
解决办法
针对以上问题,你可以按以下步骤修改代码:
1. 移除多余的Include语句
既然你已经通过投影明确指定了要加载的关联数据,Include在这里完全多余,反而会干扰EF的查询生成。
2. 将投影中的IEnumerable转换为List
在CustomFields的Select操作后添加.ToList(),确保EF能将这部分逻辑转换为有效的SQL子查询,避免延迟加载相关的问题。
3. 增加导航属性的null检查(可选但推荐)
为Address1添加null检查,避免后续可能出现的NullReferenceException。
修改后的代码示例
var customers = this._databaseContext.Customers.AsNoTracking() .Where(p => p.customerActive.HasValue && p.customerActive.Value) // 移除了多余的Include语句 .Select(c => new CustomerWithAddressDao { Id = c.customerID, Name = c.customerName, Address = c.Address1 != null ? new AddressDao { Street = c.Address1.street, Street2 = c.Address1.street2, City = c.Address1.city, StateId = c.Address1.stateID, Zip = c.Address1.zip, Zip4 = c.Address1.zip4, CountryId = c.Address1.countryID, Latitude = c.Address1.Latitude, Longitude = c.Address1.Longitude, County = c.Address1.County } : null, Sites = c.Sites.Where(s => s.IsActive.HasValue && s.IsActive.Value) .Select(q => new SiteSlimDao { Id = q.Id, Name = q.Name, CustomerId = c.customerID, CustomFields = q.SiteCustomFields.Select(a => a.Value).ToList(), // 转为List Buildings = q.Buildings.Where(b => b.buildingActive.HasValue && b.buildingActive.Value) .Select(m => new BuildingSlimDao { Id = m.buildingID, Name = m.buildingName, SiteId = q.Id, CustomFields = m.BuildingCustomFields.Select(a => a.Value).ToList(), // 转为List BuildingTypeId = m.buildingTypeID }).OrderBy(b => b.Name).ToList() }).OrderBy(s => s.Name).ToList() }) .OrderBy(customer => customer.Name) .ToList();
额外检查点
确保你的实体类(Customer、Site、Building)的导航属性(比如Sites、Buildings)定义为ICollection<T>类型,而不是IEnumerable<T>,这样EF才能正确解析关联关系,生成有效的SQL查询。
内容的提问来源于stack exchange,提问作者VIkas

