簡體   English   中英

各種派生類型集合上的通用LINQ to SQL擴展方法

[英]Generic LINQ to SQL Extension Methods on collection of various derived types

我正在嘗試為IQueryable<T>創建通用擴展方法。 T是一個抽象Player ,IQueryable可以包含具體類型的GoalkeeperStriker

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; }
}

有效的擴展方法(簡單的方法)如下所示:

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));
}

我可以這樣使用:

var badGoalies = players.OfType<Goalkeeper>().NotPerforming();
var badStrikers = players.OfType<Striker>().NotPerforming();

所以現在我想查詢所有表現不佳的球員

var badPlayers = players.NotPerforming();

我似乎無法正常工作。

public static IQueryable<T> NotPerforming<T>(this IQueryable<T> players)
    where T : Player
{
    // what to do here?
}

我嘗試過類似...

return players.OfType<Striker>().NotPerforming()
          .Union(
              players.OfType<Goalkeeper>().NotPerforming()
          );

這不起作用。

這樣做的最佳實踐方法是什么?並且不離開LINQ-to-SQL,因為我想保持鏈接擴展方法的性能,並牢記良好的性能?

您可以創建另一個擴展方法,並在其中添加邏輯:

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));
}

並使用:

var badPlayers = players.NotPerforming();

或另一種方法:

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));
}

並使用:

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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM