C# 选择->;集团->;订单->;在一个存储库功能中选择
我知道标题不好 我有一个包含所有实体函数的服务 在我的服务中,有一个具有这种结构的功能C# 选择->;集团->;订单->;在一个存储库功能中选择,c#,entity-framework,repository-pattern,C#,Entity Framework,Repository Pattern,我知道标题不好 我有一个包含所有实体函数的服务 在我的服务中,有一个具有这种结构的功能 IList<T> GetAllPaged<TKey>( List<Expression<Func<T, bool>>> predicate, Expression<Func<T, TKey>> orderKeySelector ); IList GetAllPaged( 列表谓词, 表达式顺序键选择器 );
IList<T> GetAllPaged<TKey>(
List<Expression<Func<T, bool>>> predicate,
Expression<Func<T, TKey>> orderKeySelector
);
IList GetAllPaged(
列表谓词,
表达式顺序键选择器
);
此函数从一个实体获取数据并对其进行排序
现在我想做更多
首先从一个实体中选择,然后按顺序将其分组,最后从分组的项目中选择新项目
大概是这样的:
IList<TReturn> GetAllPaged<TResult, TKey, TGroup, TReturn>(
List<Expression<Func<T, bool>>> predicate,
Expression<Func<T, TResult>> firstSelector,
Expression<Func<TResult, TKey>> orderSelector,
Func<TResult, TGroup> groupSelector,
Func<IGrouping<TGroup, TResult>, TReturn> selector
);
IList GetAllPaged(
列表谓词,
表达式第一选择器,
表达式顺序选择器,
Func组选择器,
函数选择器
);
这是可能的吗?也许您可以传递一个通用函数来处理您的实体? 我知道表达是有趣的,但是你应该总是考虑最终结果是否比简单的东西好。 大概是这样的:
TResult Query<TEntity, TResult>(Func<IQueryable<TEntity>, TResult> queryFunction)
如果将所有这些逻辑放在单独的参数中,您将失去使用匿名对象的能力,并且您将发现自己编写了许多服务方法 这是一个解决你所要求的问题的方法 首先,基本存储库。我创建了一个基本存储库,因为我希望您不要将这种疯狂行为暴露给应用程序,而只暴露给存储库
abstract class BaseRepo<TEntity>
{
// If you're using Entity Framework, this method could
// be implemented here instead.
protected abstract IQueryable<TEntity> Entities { get; }
protected IList<TReturn> GetAllPaged<TResult, TKey, TGroup, TReturn>(
List<Expression<Func<TEntity, bool>>> predicates,
Expression<Func<TEntity, TResult>> firstSelector,
Expression<Func<TResult, TKey>> orderSelector,
Func<TResult, TGroup> groupSelector,
Func<IGrouping<TGroup, TResult>, TReturn> selector)
{
return predicates
.Aggregate(Entities, (current, predicate) => current.Where(predicate))
.Select(firstSelector)
.OrderBy(orderSelector)
.GroupBy(groupSelector)
.Select(selector)
.ToList();
}
}
抽象类BaseRepo
{
//如果您使用的是实体框架,则此方法可能
//而是在这里实施。
受保护的抽象IQueryable实体{get;}
受保护的IList GetAllPaged(
列出谓词,
表达式第一选择器,
表达式顺序选择器,
Func组选择器,
Func选择器)
{
返回谓词
.Aggregate(实体,(当前,谓词)=>current.Where(谓词))
.选择(第一选择器)
.OrderBy(orderSelector)
.GroupBy(groupSelector)
.选择(选择器)
.ToList();
}
}
然后是实施
class HorseRepo : BaseRepo<Horse>
{
// This will of course be some data source
protected override IQueryable<Horse> Entities
{
get
{
return new List<Horse> {
new Horse { Id = 1, Name = "Mr Horse", Color = "Brown" },
new Horse { Id = 2, Name = "Mrs Horse", Color = "White" },
new Horse { Id = 3, Name = "Jr Horse", Color = "White" },
new Horse { Id = 4, Name = "Sr Horse", Color = "Black" },
new Horse { Id = 5, Name = "Dr Horse", Color = "Brown" },
}.AsQueryable();
}
}
// This is what I think you should expose to the application
// This is the usage of the expression fest above.
public IEnumerable<GroupedHorses> GetGroupedByColor() {
return horseRepo.GetAllPaged(
new List<Expression<Func<Horse, bool>>> {
h => h.Name != string.Empty,
h => h.Id > 0
},
h => new HorseShape { Id = h.Id, Name = h.Name, Color = h.Color },
hs => hs.Name,
hs => hs.Color,
g => new GroupedHorses
{
Color = g.Key,
Horses = g.ToList()
}
);
}
}
class HorseRepo:BaseRepo
{
//这当然是一些数据源
受保护的可重写实体
{
得到
{
返回新列表{
新马{Id=1,Name=“mrhorse”,Color=“Brown”},
新马{Id=2,Name=“Mrs Horse”,Color=“White”},
新马{Id=3,Name=“Jr Horse”,Color=“White”},
新马{Id=4,Name=“Sr Horse”,Color=“Black”},
新马{Id=5,Name=“drhorse”,Color=“Brown”},
}.AsQueryable();
}
}
//这就是我认为您应该向应用程序公开的内容
//这是上面表达式fest的用法。
公共IEnumerable GetGroupedByColor(){
返回horseRepo.GetAllPaged(
新名单{
h=>h.Name!=string.Empty,
h=>h.Id>0
},
h=>newhorseshape{Id=h.Id,Name=h.Name,Color=h.Color},
hs=>hs.Name,
hs=>hs.Color,
g=>新群马
{
颜色=g.键,
马=g.托利斯特()
}
);
}
}
需要一些课程:
class GroupedHorses
{
public string Color { get; set; }
public IList<HorseShape> Horses { get; set; }
}
class HorseShape
{
public int Id { get; set; }
public string Name { get; set; }
public string Color { get; set; }
}
// Define other methods and classes here
class Horse
{
public int Id { get; set; }
public string Name { get; set; }
public string Color { get; set; }
public string UninterestingProperty { get; set; }
}
class-GroupedHorses
{
公共字符串颜色{get;set;}
公共IList马{get;set;}
}
马形类
{
公共int Id{get;set;}
公共字符串名称{get;set;}
公共字符串颜色{get;set;}
}
//在此处定义其他方法和类
班马
{
公共int Id{get;set;}
公共字符串名称{get;set;}
公共字符串颜色{get;set;}
公共字符串UntrestingProperty{get;set;}
}
在您的示例中,使用了T
,但声明不包含它。它应该是哪一个?它是我的实体。在我的代码中,它是这样的->T.Where(谓词)。Select(fristSelector)firstSelector的角色是什么?firstSelector
?有人对表达式发疯了,爱死它了!:)firstSelector的用途是什么?从我的实体中选择所需的属性。也许我的实体有20个财产,而我只需要其中的5个。在第一次之后,选择i组并订购。
class HorseRepo : BaseRepo<Horse>
{
// This will of course be some data source
protected override IQueryable<Horse> Entities
{
get
{
return new List<Horse> {
new Horse { Id = 1, Name = "Mr Horse", Color = "Brown" },
new Horse { Id = 2, Name = "Mrs Horse", Color = "White" },
new Horse { Id = 3, Name = "Jr Horse", Color = "White" },
new Horse { Id = 4, Name = "Sr Horse", Color = "Black" },
new Horse { Id = 5, Name = "Dr Horse", Color = "Brown" },
}.AsQueryable();
}
}
// This is what I think you should expose to the application
// This is the usage of the expression fest above.
public IEnumerable<GroupedHorses> GetGroupedByColor() {
return horseRepo.GetAllPaged(
new List<Expression<Func<Horse, bool>>> {
h => h.Name != string.Empty,
h => h.Id > 0
},
h => new HorseShape { Id = h.Id, Name = h.Name, Color = h.Color },
hs => hs.Name,
hs => hs.Color,
g => new GroupedHorses
{
Color = g.Key,
Horses = g.ToList()
}
);
}
}
class GroupedHorses
{
public string Color { get; set; }
public IList<HorseShape> Horses { get; set; }
}
class HorseShape
{
public int Id { get; set; }
public string Name { get; set; }
public string Color { get; set; }
}
// Define other methods and classes here
class Horse
{
public int Id { get; set; }
public string Name { get; set; }
public string Color { get; set; }
public string UninterestingProperty { get; set; }
}