【问题标题】:c# predefine LINQ select [duplicate]c# 预定义 LINQ 选择 [重复]
【发布时间】:2013-03-01 13:25:35
【问题描述】:

我想将相同的SELECT 应用于queries 的金额,我该怎么做?我想制作某种模板?

var query = (from b in db.routes select new 
{ name = b.name,
age = b.age});

我想预定义 name=b.name 和 age = b.age。

谢谢

【问题讨论】:

  • 请出示您的代码!!以便其他人可以帮助您
  • 您确实需要更具体才能获得答案。
  • 所有查询都处理相同的源类型吗?
  • 请不要重复您自己的问题。与前一个相比,这个信息甚至更少

标签: c# linq select


【解决方案1】:

您可以使用IEnumerable<SomeBaseClassOrInterfacee> 参数创建方法。 那么你可以在方法中对给定的参数进行选择。

public class Generic
{
    protected Generic(string name, int age)
    {
        Name = name;
        Age = age;
    }

    public string Name { get; private set; }
    public int Age { get; private set; }
}

public class Human : Generic 
{
    public Human(string name, string surname, int age) : base(name, age)
    {
        Surname = surname;
    }

    public string Surname { get; private set; }
}

public class Pet : Generic
{
    public Pet(string name, int registrationCode, int age)
        : base(name, age)
    {
        RegistrationCode = registrationCode;
    }

    public int RegistrationCode { get; private set; }
}


static void Main(string[] args)
{
    IEnumerable<Pet> pets = new List<Pet>();
    IEnumerable<Human> palls = new List<Human>();

    var resPets = SelectAgeGreaterThen10<Pet>(from p in pets where p.Name.StartsWith("A") select p);
    var resHumans = SelectAgeGreaterThen10<Human>(from p in palls where p.Name.StartsWith("B") select p);

}

private static IEnumerable<T> SelectAgeGreaterThen10<T>(IEnumerable<Generic> source) where T : Generic
{
    return from s in source where s.Age > 10 select (T)s;
}

【讨论】:

  • 你能举个例子吗?
  • 问题是我对许多查询使用相同的 SELECT,如果我想更新我的选择,我只想在一个地方更改代码,比如模板。即使我为我的选择做一个界面,我仍然必须在选择中设置数据。
【解决方案2】:

您的示例的棘手之处在于您使用的是匿名类型 - 这意味着您无法编写方法(您无法声明返回类型)并且您无法将 lambda 表达式分配给本地变量(您需要能够指定将 lambda 表达式转换为的类型)。

不能只使用类型推断从泛型方法返回某些内容 - 因为您不能只指定输入类型。但是,您可以对泛型类使用类型推断:

public static class Functions<T>
{
    public static Func<T, TResult> Create<TResult>(Func<T, TResult> func)
    {
        return func;
    }
}

然后你可以写:

var projection = Functions<Route>.Create(r => new { r.name, r.age });

var query = db.routes
              .Select(projection)
              ...;

但如果你真的想在多个地方使用相同的投影,你应该考虑创建一个命名的结果类型——此时你可以使用任何其他选项,包括转换方法.

【讨论】:

  • 我创建了方法(IEnumerable x),它接受查询作为匿名类型,我可以执行 x.Select,但是我不能在其中使用任何 lambda 表达式,我不断收到“不能使用 lambda 表达式作为动态调度操作的参数,除非先将其转换为委托或表达式树类型”
  • @user2049921:我可能是错的,但听起来你可能有点超出你的深度。我会强烈建议不要使用动态类型,直到您真正熟悉 C# 的一般工作方式。
  • 这实际上超出了我的深度,但它是我真正想解决的项目的一部分,遗憾的是没有时间重写非常需要的大部分代码。
  • @user2049921:编写你并不真正理解的代码会花费你的时间,从长远来看当然也很可能在短期内。
  • 我可以为我的所有查询创建类型以摆脱匿名类型问题,我可能不得不这样做。但是我想知道是否有可能使整个 IEnumreable 和 lambda 表达式工作?
【解决方案3】:

这看起来怎么样:

class NameAndAge
{
    public String Name;
    public Int32 Age;
}

class Whatever
{
    public IEnumerable<NameAndAge> GetNameAndAges(IEnumerable<dynamic> enumerable)
    {
         return from b in enumerable select new NameAndAge { Name = b.name,
                                                             Age = b.age};
    } 
}

您可能希望将参数类型中的dynamic 替换为db.routes 中元素的类型。

【讨论】:

  • 实际上看起来很像this。 =)
  • 这就是我现在正在做的事情,但是我想在那个 Select 中使用 lambda 表达式,我不知道如何解决“”不能使用 lambda 表达式作为动态的参数调度操作,而不首先将其转换为委托或表达式树类型”
  • 将其转换为委托或表达式树?或者您可以按照我在答案中的建议进行操作,并将 dynamic 更改为真实类型。
猜你喜欢
  • 2023-02-25
  • 1970-01-01
  • 2011-03-30
  • 2015-03-17
  • 1970-01-01
  • 1970-01-01
  • 2013-07-18
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多