[英]Generic LINQ to SQL Extension Methods on collection of various derived types
I'm trying to create a generic extension method for an IQueryable<T>
. 我正在尝试为IQueryable<T>
创建通用扩展方法。 T is an abstract Player
and the IQueryable can contain concrete types Goalkeeper
and Striker
. T是一个抽象Player
,IQueryable可以包含具体类型的Goalkeeper
和Striker
。
public abstract class Player
{
public string Name { get; set; }
public string Fouls { get; set; }
}
public class Goalkeeper : Player
{
public int Saves { get; set; }
}
public class Striker : Player
{
public int Goals { get; set; }
}
The extension methods that are working (the simple ones) look like this: 有效的扩展方法(简单的方法)如下所示:
public static IQueryable<Goalkeeper> NotPerforming(this IQueryable<Goalkeeper> goalkeepers)
{
return goalkeepers.Where(g => g.Saves < goalkeepers.Average(x => x.Saves));
}
public static IQueryable<Striker> NotPerforming(this IQueryable<Striker> strikers)
{
return strikers.Where(g => g.Goals < strikers.Average(x => x.Goals));
}
Which I can use like this: 我可以这样使用:
var badGoalies = players.OfType<Goalkeeper>().NotPerforming();
var badStrikers = players.OfType<Striker>().NotPerforming();
So now I want to query for all players who are not performing well. 所以现在我想查询所有表现不佳的球员 。
var badPlayers = players.NotPerforming();
Which I can't seem to get to work properly. 我似乎无法正常工作。
public static IQueryable<T> NotPerforming<T>(this IQueryable<T> players)
where T : Player
{
// what to do here?
}
I tried things like... 我尝试过类似...
return players.OfType<Striker>().NotPerforming()
.Union(
players.OfType<Goalkeeper>().NotPerforming()
);
Which doesn't work. 这不起作用。
What is the best practice way of doing this -- and without leaving LINQ-to-SQL because I'd like to keep chaining extension methods -- and keeping good performance in mind? 这样做的最佳实践方法是什么?并且不离开LINQ-to-SQL,因为我想保持链接扩展方法的性能,并牢记良好的性能?
You can create another extension method and put there a logic: 您可以创建另一个扩展方法,并在其中添加逻辑:
public static IQueryable<Player> NotPerforming(this IQueryable<Player> players)
{
var notPerformingGoalKeepers = players.NotPerformingGoalkeepers();
var notPerformingStrikers = players.NotPerformingStrikers();
return notPerformingGoalKeepers.Cast<Player>()
.Concat(notPerformingStrikers);
}
public static IQueryable<Goalkeeper> NotPerformingGoalkeepers(this IQueryable<Player> players)
{
var goalkeepers = players.OfType<Goalkeeper>();
return goalkeepers.Where(g => g.Saves < goalkeepers.Average(x => x.Saves));
}
public static IQueryable<Striker> NotPerformingStrikers(this IQueryable<Player> players)
{
var strikers = players.OfType<Striker>();
return strikers.Where(g => g.Goals < strikers.Average(x => x.Goals));
}
And use: 并使用:
var badPlayers = players.NotPerforming();
Or another approach: 或另一种方法:
public static IQueryable<Player> NotPerforming<T>(this IQueryable<Player> players) where T : Player
{
if (typeof(T) == typeof(Goalkeeper))
{
return players.OfType<Goalkeeper>().NotPerforming();
}
if (typeof(T) == typeof(Striker))
{
return players.OfType<Striker>().NotPerforming();
}
return null;
}
private static IQueryable<Goalkeeper> NotPerforming(this IQueryable<Goalkeeper> goalkeepers)
{
return goalkeepers.Where(g => g.Saves < goalkeepers.Average(x => x.Saves));
}
private static IQueryable<Striker> NotPerforming(this IQueryable<Striker> strikers)
{
return strikers.Where(g => g.Goals < strikers.Average(x => x.Goals));
}
And use: 并使用:
var badStrikers = players.NotPerforming<Striker>();
var badGoalkeepers = players.NotPerforming<Goalkeeper>();
var badPlayers = players.NotPerforming<Striker>()
.Concat(players.NotPerforming<Goalkeeper>());
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.