Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/vim/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 将逻辑从lambda表达式拆分为多个LINQ表达式_C#_Linq_Lambda_Linq To Entities - Fatal编程技术网

C# 将逻辑从lambda表达式拆分为多个LINQ表达式

C# 将逻辑从lambda表达式拆分为多个LINQ表达式,c#,linq,lambda,linq-to-entities,C#,Linq,Lambda,Linq To Entities,下面的代码示例说明了我的问题。 我如何将lambda的一部分放置在其他地方 如何从“GetGurus()”方法调用“Foo”? 我希望LINQ将其转换为1语句 public enum GuruLevel { NotSet, Goku, SuperSayan } private IEnumerable<PersonInfo> GetGurus() { using (var context = new CRMContext()) {

下面的代码示例说明了我的问题。 我如何将lambda的一部分放置在其他地方

如何从“GetGurus()”方法调用“Foo”? 我希望LINQ将其转换为1语句

public enum GuruLevel
 {
    NotSet,
    Goku,
    SuperSayan
}

 private IEnumerable<PersonInfo> GetGurus()
 {
    using (var context = new CRMContext())
    {
        var persons = context.Person
            .Where(p => p.Experience > 10)
            .OrderBy(p => p.DateOfBirth)
            .Select(p => new PersonInfo())
            {
                StackOverFlowName = p.StackOverFlowName,
                Experience = p.Experience,
                GuruStatus = Foo //(p.Experience > 9000) ? GuruLevel.SuperSayan : GuruLevel.Goku
            }
        return persons.ToList();
    } 
 }

public static System.Linq.Expressions.Expression<Func<Person, GuruLevel>> Foo
{
    get
    {
        return bar => (bar.Experience > 9000) ? GuruLevel.SuperSayan : GuruLevel.Goku;
    }
}
public enum GuruLevel
{
未设置,
小悟空,
超级萨扬
}
私有IEnumerable GetGurus()
{
使用(var context=new CRMContext())
{
var persons=context.Person
.其中(p=>p.经验>10)
.OrderBy(p=>p.DateOfBirth)
.Select(p=>newpersoninfo())
{
StackOverFlowName=p.StackOverFlowName,
经验,经验,
GuruStatus=Foo/(p.Experience>9000)?GuruLevel.SuperSayan:GuruLevel.Goku
}
返回人员。ToList();
} 
}
public static System.Linq.Expressions.Expression Foo
{
得到
{
返回条=>(bar.Experience>9000)?GuruLevel.SuperSayan:GuruLevel.Goku;
}
}
更改此项

public static Func<Person, GuruLevel> Foo
{
    get
    {
        return bar => (bar.Experience > 9000) ? GuruLevel.SuperSayan : GuruLevel.Goku;
    }
}
改变这一点

public static Func<Person, GuruLevel> Foo
{
    get
    {
        return bar => (bar.Experience > 9000) ? GuruLevel.SuperSayan : GuruLevel.Goku;
    }
}

此逻辑由
PersonInfo
类负责。此代码通常放在构造函数或工厂类中,并且完全符合单一责任原则

class PersonInfo
{
    public string StackOverFlowName { get; set; }
    public int Experience { get; set; }
    public GuruLevel GuruStatus { get; set; }

    public void PersonInfo(Person p)
    {
      StackOverFlowName = p.StackOverFlowName;
      Experience = p.Experience;
      GuruStatus = p.Experience > 9000 ? GuruLevel.SuperSayan : GuruLevel.Goku;
    }
}
然后将您的服务方法更改为:

private IEnumerable<PersonInfo> GetGurus()
{
   using (var context = new CRMContext())
   {
       var persons = context.Person
           .Where(p => p.Experience > 10)
           .OrderBy(p => p.DateOfBirth)
           .ToList()
           .Select(p => new PersonInfo(p))
       return persons.ToList();
   } 
}

此逻辑由
PersonInfo
类负责。此代码通常放在构造函数或工厂类中,并且完全符合单一责任原则

class PersonInfo
{
    public string StackOverFlowName { get; set; }
    public int Experience { get; set; }
    public GuruLevel GuruStatus { get; set; }

    public void PersonInfo(Person p)
    {
      StackOverFlowName = p.StackOverFlowName;
      Experience = p.Experience;
      GuruStatus = p.Experience > 9000 ? GuruLevel.SuperSayan : GuruLevel.Goku;
    }
}
然后将您的服务方法更改为:

private IEnumerable<PersonInfo> GetGurus()
{
   using (var context = new CRMContext())
   {
       var persons = context.Person
           .Where(p => p.Experience > 10)
           .OrderBy(p => p.DateOfBirth)
           .ToList()
           .Select(p => new PersonInfo(p))
       return persons.ToList();
   } 
}

这不是你问题的直接答案,但它与你问的原因有关

我假设,您使用的是某种数据库,所以您不能使用常规方法,因为它们不会被数据库的上下文所知道

例如,您实际上可以执行私有方法来处理数据,但不能使用自定义类型或类。在您的示例中,“GuruLevel”不会被DB识别

我建议不要尝试在DB端进行转换。取而代之的是以DB格式检索所有需要的数据,并在应用程序端进行转换

using (var context = new CRMContext())
{
    var persons = context.Person
        .Where(p => p.Experience > 10)
        .OrderBy(p => p.DateOfBirth)
        .Select(p => new {p.StackOverFlowName, p.Experience }) //or whole object, or other fields if needed
        .ToList() //executes query, all following code will be in a context of application not DB
        .Select(p => new PersonInfo())
        {
            StackOverFlowName = p.StackOverFlowName,
            Experience = p.Experience,
            GuruStatus = GetGuruStatus(p.Experience)
        }
    return persons.ToList();
}

private GuruLevel GetGuruLevel(int exp)
{
    return exp > 9000 ? GuruLevel.SuperSayan : GuruLevel.Goku
}

这不是你问题的直接答案,但它与你问的原因有关

我假设,您使用的是某种数据库,所以您不能使用常规方法,因为它们不会被数据库的上下文所知道

例如,您实际上可以执行私有方法来处理数据,但不能使用自定义类型或类。在您的示例中,“GuruLevel”不会被DB识别

我建议不要尝试在DB端进行转换。取而代之的是以DB格式检索所有需要的数据,并在应用程序端进行转换

using (var context = new CRMContext())
{
    var persons = context.Person
        .Where(p => p.Experience > 10)
        .OrderBy(p => p.DateOfBirth)
        .Select(p => new {p.StackOverFlowName, p.Experience }) //or whole object, or other fields if needed
        .ToList() //executes query, all following code will be in a context of application not DB
        .Select(p => new PersonInfo())
        {
            StackOverFlowName = p.StackOverFlowName,
            Experience = p.Experience,
            GuruStatus = GetGuruStatus(p.Experience)
        }
    return persons.ToList();
}

private GuruLevel GetGuruLevel(int exp)
{
    return exp > 9000 ? GuruLevel.SuperSayan : GuruLevel.Goku
}


感谢您的尝试,但这会导致:“LINQ to实体中不支持LINQ表达式节点类型‘Invoke’。@Tony_Kilopamikegolf如果答案适用于LINQ to对象;你没有说明你是在没有注意的情况下工作的。我不知道是EF。也许我的编辑会工作,因为它是一个标准的功能。不确定。我不使用EFQ谢谢您的尝试,但这会导致:“LINQ to实体中不支持LINQ表达式节点类型‘Invoke’。@Tony_Kilopamikegolf答案在LINQ to对象中有效;你没有说明你是在没有注意的情况下工作的。我不知道是EF。也许我的编辑会工作,因为它是一个标准的功能。不确定。我不使用EFIf
CrmContext
是EF6,这将在查询转换期间在运行时崩溃。不支持带参数的构造函数。我喜欢它,但问题是关于拆分lambda的。仍然+1@Impworks没错,他可能会在初始化之前执行此查询。@bixarrio我试图避免生成更多代码气味样本的答案。如果作者知道
Expression
类,我假设他能够将这个属性转换成一个方法。在现实世界中,“GuruLevel”是在PersonInfo中没有的、但可以亲自使用的更多字段上计算的。如果
CrmContext
是EF6,则在查询转换过程中,这将在运行时崩溃。不支持带参数的构造函数。我喜欢它,但问题是关于拆分lambda的。仍然+1@Impworks没错,他可能会在初始化之前执行此查询。@bixarrio我试图避免生成更多代码气味样本的答案。如果作者知道
Expression
类,我假设他能够将这个属性转换成一个方法。在现实世界中,“GuruLevel”是根据更多的字段计算的,这些字段在PersonInfo中不可用,但可以亲自使用。我正在阅读您的链接,似乎这正是我需要的。尽管实施起来似乎相当复杂:(遗憾的是,你没有发布答案,因为你给出了最好的答案!我安装了。它很有效!事实上,这个问题与我提到的问题是重复的。理想情况下,它应该因此而关闭。我们的最终用户现在也非常高兴!我们项目查询的性能提升超出了预期!我很喜欢it!我正在阅读您的链接,似乎这正是我所需要的。尽管实现起来似乎相当复杂:(遗憾的是,你没有发布答案,因为你给出了最好的答案!我安装了。它很有效!事实上,这个问题与我提到的问题是重复的。理想情况下,它应该因此而关闭。我们的最终用户现在也非常高兴!我们项目查询的性能提升超出了预期!我很喜欢信息技术