我试图重做此方法只返回相应的记录。下面的原始GetAll()返回了许多不必要的列和数据,因为正在使用EF代理。关闭EF代理会破坏应用程序中的内容,因此我尝试有选择地减少返回的数据以提高性能。
原创GetAll()
public IEnumerable<OWF_ManagerRelationship> GetAll()
{
return context.OWF_ManagerRelationship.Where(x => x.IsActive == true).ToList();
}
我试图创建的新GetAll()如下所示。这个将包含来自注释掉的Include()语句中的OWF_Onsites表的一些字段。这些将是几个日期字段和一个整数字段。这是我试图减少从此方法返回到调用方法的数据量的地方。我想从Owf_ManagerRelationship上下文返回一个DisplayName字段,从OWF_Onsites表中返回另一个3(OnsiteDate,TargetDate,TargetMonth)。
public IEnumerable<string> GetAll()
{
var managers = context.OWF_ManagerRelationship
.Where(m => m.IsActive.Value == true)
//.Include(o => o.OWF_Onsites).Where()
.Select(x => new {x.DisplayName})
.ToList();
return managers;
}
上面的return managers
有红色的波浪线。它表示&#34;无法将表达式System.Collections.Generic.List<DisplayName:string>
转换为返回类型System.Collections.Generic.IEnumerable<string>
&#34;。
我知道它无法将匿名类型字符串DisplayName转换为返回类型字符串,但我并不理解为什么。我认为它会起作用,因为DisplayName是一个字符串。一旦我在Include()语句中运行代码,我也不明白返回类型应该是什么。一旦完成,它还应该从OWF_Onsites返回两个日期字段和一个整数字段。
有人可以对这应该是什么样子有所了解吗?包含一些代码以及如何使用Include()中OWF_Onsites表中的两个日期字段(targetDate和OnsiteDate)和整数(TargetMonth)字段将非常有用。
希望我的意图很清楚,以防我尝试这样做是偏离基础的。如果我做错了,请告诉我。
答案 0 :(得分:5)
您正在尝试返回IEnumerable
匿名类型而不是IEnumerable<string>
。删除选择中的new
,它将起作用:
public IEnumerable<string> GetAll()
{
var managers = context.OWF_ManagerRelationship
.Where(m => m.IsActive.Value == true)
.Select(x => x.DisplayName)
.ToList();
return managers;
}
其他一些值得注意的事项:
您也可以省略.ToList()
来简化代码,因为.Select
已经返回IEnumerable<string>
。请注意,您仍需要稍后枚举查询(例如,使用ToList
)以获取结果,因为延迟执行。
public IEnumerable<string> GetAll()
{
var managers = context.OWF_ManagerRelationship
.Where(m => m.IsActive.Value == true)
.Select(x => x.DisplayName);
return managers;
}
答案 1 :(得分:2)
你应该看看IQueryable预测来做你想做的事情。以下是一些关于入门的精彩博文:
通过使用这些概念,我能够编写如下的通用存储库方法:
public IEnumerable<T> GetAllProjectTo<T>(params Expression<Func<TEntity, bool>>[] filters)
{
var query = Table.AsQueryable();
if (filters != null)
{
query = filters.Aggregate(query, (current, where) => current.Where(where));
}
return query.Project().To<T>().AsEnumerable();
}
这意味着如果我有这个数据定义(EF):
public class FullModel
{
public int Id { get; set; }
public string Title { get; set; }
public string Description { get; set; }
public int QuantityOnHand { get; set; }
public double UnitCost { get; set; }
public DateTime Created { get; set; }
public string CreatedBy { get; set; }
public DateTime Updated { get; set; }
public string UpdatedBy { get; set; }
}
我只想从数据中获得这种表示:
public class ShortModel
{
public int Id { get; set; }
public string Title { get; set; }
public int QuantityOnHand { get; set; }
public double UnitCost { get; set; }
}
我现在可以这样做:
IEnumerable<ShortModel> results = _repository.GetAllProjectTo<ShortModel>(a => a.Title.Contains("milk"));
上面的秘诀是Project()和To()的定义。 (请仔细阅读我发布的第二篇博客中的示例。)这两种方法协同工作会影响发送到SQL Server的SQL。在上面的代码示例中,即使使用Select,它也会发出 SELECT * FROM 命令,然后在实现过程中应用SELECT。这意味着,所有受影响的行中的所有数据都将首先返回给您!
在您的情况下,它可能看起来像:
public class MyViewModel
{
// Name of field MUST match name of field in EF/ORM...
public string DisplayName { get; set; }
}
public IEnumerable<string> GetAllManagers()
{
var displayList = context.OWF_ManagerRelationship
.Where(m => m.IsActive.Value == true)
.Project()
.To<MyViewModel>()
.ToList();
IEnumerable<string> managers = displayList.Select(a => a.DisplayName).ToList();
return managers;
}