当我尝试使用实体 EF6 获取行时出现错误
Getting error when I try to fetch rows using entity EF6
我先使用 linq to entity 6 代码。
这里有两个实体class:
public class Site
{
public int Id { get; set; }
public int UID { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public int? ContractId { get; set; }
public int? SiteTypeId { get; set; }
public virtual ICollection<SiteRegion> Regions { get; set; }
}
public class SiteRegion
{
public int Id { get; set; }
public int UID { get; set; }
public int? SiteId { get; set; }
public string Name { get; set; }
public int? RegionTypeId { get; set; }
[ForeignKey("SiteId")]
public virtual Site Site { get; set; }
}
正如您在上面看到的那样,Regions 字段是约束条件,我与 tables 之间存在一对多关系。
我创建了这个 LINQ 查询来从网站中获取所需的行 table:
int?[] ContractId = [1,2];
int?[] siteTypeId = [1,2,3];
var result = (from sites in context.Set<Site>()
where contractsIDList.Contains(sites.ContractId) &&
siteTypeId.Contains(sites.SiteTypeId) &&
select sites).AsNoTracking<Site>();
而且效果很好。
现在我有新的要求,我还需要通过 SiteRegion table 中的 RegionTypeId
列来过滤我的查询,这是我的新查询:
int?[] ContractId = [1,2];
int?[] siteTypeId = [1,2,3];
int?[] regionTypeId = [1,2,3];
var result = (from sites in context.Set<Site>()
where contractsIDList.Contains(sites.ContractId) &&
siteTypeId.Contains(sites.SiteTypeId) &&
regionTypeId.Contains(sites.Regions.SelectMany(x=>x.RegionTypeId).ToArray())
select sites).AsNoTracking<Site>();
但是我得到错误:
Error 36 'int?[]' does not contain a definition for 'Contains' and the best extension method overload 'System.Linq.Queryable.Contains<TSource>(System.Linq.IQueryable<TSource>, TSource)' has some invalid arguments
这一行:
regionTypeId.Contains(sites.Regions.SelectMany(x=>x.RegionTypeId).ToArray())
如何修正上面的查询以获得所需的行?
您需要按照下图进行。
注:
错误 : regionTypeId.Contains(sites.Regions.SelectMany(x=>x.RegionTypeId).ToArray())
正确: regionTypeId.Any(item => sites.Regions.Select(x => x.RegionTypeId).Contains(item))
工作样本:
int?[] contractsIDList = { 1, 2};
int?[] siteTypeId = { 1, 2, 3};
int?[] regionTypeId = { 1, 2, 3};
var result = (from sites in db.Set<Site>()
where contractsIDList.Contains(sites.ContractId) && siteTypeId.Contains(sites.SiteTypeId)
&& regionTypeId.Any(item => sites.Regions.Select(x => x.RegionTypeId).Contains(item))
select sites).AsNoTracking<Site>();
结果:
我先使用 linq to entity 6 代码。
这里有两个实体class:
public class Site
{
public int Id { get; set; }
public int UID { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public int? ContractId { get; set; }
public int? SiteTypeId { get; set; }
public virtual ICollection<SiteRegion> Regions { get; set; }
}
public class SiteRegion
{
public int Id { get; set; }
public int UID { get; set; }
public int? SiteId { get; set; }
public string Name { get; set; }
public int? RegionTypeId { get; set; }
[ForeignKey("SiteId")]
public virtual Site Site { get; set; }
}
正如您在上面看到的那样,Regions 字段是约束条件,我与 tables 之间存在一对多关系。
我创建了这个 LINQ 查询来从网站中获取所需的行 table:
int?[] ContractId = [1,2];
int?[] siteTypeId = [1,2,3];
var result = (from sites in context.Set<Site>()
where contractsIDList.Contains(sites.ContractId) &&
siteTypeId.Contains(sites.SiteTypeId) &&
select sites).AsNoTracking<Site>();
而且效果很好。
现在我有新的要求,我还需要通过 SiteRegion table 中的 RegionTypeId
列来过滤我的查询,这是我的新查询:
int?[] ContractId = [1,2];
int?[] siteTypeId = [1,2,3];
int?[] regionTypeId = [1,2,3];
var result = (from sites in context.Set<Site>()
where contractsIDList.Contains(sites.ContractId) &&
siteTypeId.Contains(sites.SiteTypeId) &&
regionTypeId.Contains(sites.Regions.SelectMany(x=>x.RegionTypeId).ToArray())
select sites).AsNoTracking<Site>();
但是我得到错误:
Error 36 'int?[]' does not contain a definition for 'Contains' and the best extension method overload 'System.Linq.Queryable.Contains<TSource>(System.Linq.IQueryable<TSource>, TSource)' has some invalid arguments
这一行:
regionTypeId.Contains(sites.Regions.SelectMany(x=>x.RegionTypeId).ToArray())
如何修正上面的查询以获得所需的行?
您需要按照下图进行。
注:
错误 : regionTypeId.Contains(sites.Regions.SelectMany(x=>x.RegionTypeId).ToArray())
正确: regionTypeId.Any(item => sites.Regions.Select(x => x.RegionTypeId).Contains(item))
工作样本:
int?[] contractsIDList = { 1, 2};
int?[] siteTypeId = { 1, 2, 3};
int?[] regionTypeId = { 1, 2, 3};
var result = (from sites in db.Set<Site>()
where contractsIDList.Contains(sites.ContractId) && siteTypeId.Contains(sites.SiteTypeId)
&& regionTypeId.Any(item => sites.Regions.Select(x => x.RegionTypeId).Contains(item))
select sites).AsNoTracking<Site>();
结果: