Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/268.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# IQueryable串联表达式_C#_Entity Framework_Linq_Expression - Fatal编程技术网

C# IQueryable串联表达式

C# IQueryable串联表达式,c#,entity-framework,linq,expression,C#,Entity Framework,Linq,Expression,假设我有一个杂志类,带有一个描述订阅周期(每月、双月、每季度等)的enum属性。选择枚举中的值可以使某些计算变得简单 使用实体框架,我有一个DbContext和一个DbSet 虽然此函数可以在IEnumerable.Select中使用,但不能在IQueryable.Select中使用。您不能在IQueryable中创建块语句。请选择 然而,到达StartPeriod和NextPeriod的计算相当简单。我想创建一个表达式树,我可以给我的Select语句 我到目前为止所做的事情 我知道如何将前几个

假设我有一个杂志类,带有一个描述订阅周期(每月、双月、每季度等)的enum属性。选择枚举中的值可以使某些计算变得简单

使用实体框架,我有一个
DbContext
和一个
DbSet

虽然此函数可以在
IEnumerable.Select中使用,但不能在
IQueryable.Select中使用。您不能在
IQueryable中创建块语句。请选择

然而,到达
StartPeriod
NextPeriod
的计算相当简单。我想创建一个表达式树,我可以给我的Select语句

我到目前为止所做的事情 我知道如何将前几个语句创建为表达式:

Expression<Func<Magazine, SupbscriptionPeriodType>> e1 = 
     magazine => magazine.SubscriptionPeriodType;
Expression<Func<SubscriptionPeriodType, int>> PeriodLength = s => (int)s;
Expression<Func<DateTime, int, int>> PeriodNr = 
    (date, periodLength) => (date.Month - 1) / periodLength;

// etc.

是否确实需要使用select在
IQueryable
中工作?我想你应该在查询端做这个逻辑。如果是这种情况,您可以将Where子句应用于IQueryable,然后将具体化的结果转换为可枚举的,例如
myMagazinesQueryable.Where(…).AsEnumerable().Select(magazine=>CalculatePeriod(magazine,date))
。您只需将
CalculatePeriod
重写为纯函数即可。我还看到我可以把语句放在几个Select语句中,一个接一个。这将生成一个SQL语句,其中包含与我想要的语句类似的临时变量。但是,一次又一次的选择看起来不太专业,很难被别人理解。。此外,我想掌握创建表达式的技能根据我的经验,编写小表达式对于创建可组合和可重用的Where子句非常有用,但我怀疑使用表达式编写Select子句会带来很多不必要的复杂性。如果选择在DB上运行Select或在C#中运行Select,我认为选择通过表达式树在数据库中运行日期逻辑不会带来任何好处(如果可能的话,我有点怀疑它会起作用)。它只是添加了更多的代码和另一个间接级别。您确定需要选择才能在
IQueryable
中工作吗?我想你应该在查询端做这个逻辑。如果是这种情况,您可以将Where子句应用于IQueryable,然后将具体化的结果转换为可枚举的,例如
myMagazinesQueryable.Where(…).AsEnumerable().Select(magazine=>CalculatePeriod(magazine,date))
。您只需将
CalculatePeriod
重写为纯函数即可。我还看到我可以把语句放在几个Select语句中,一个接一个。这将生成一个SQL语句,其中包含与我想要的语句类似的临时变量。但是,一次又一次的选择看起来不太专业,很难被别人理解。。此外,我想掌握创建表达式的技能根据我的经验,编写小表达式对于创建可组合和可重用的Where子句非常有用,但我怀疑使用表达式编写Select子句会带来很多不必要的复杂性。如果选择在DB上运行Select或在C#中运行Select,我认为选择通过表达式树在数据库中运行日期逻辑不会带来任何好处(如果可能的话,我有点怀疑它会起作用)。它只是添加了更多的代码和另一个间接层次。
Period CalculatePeriod(DateTime date) 
{
    SubscriptionPeriodType subscriptionPeriodType = dbContext.Magazines
        .Where(...)
        .Select(magazine => magazine.SubscriptionPeriodType;
    int periodLength = (int)subscriptionPeriodType;
    int periodNr = (date.Month - 1) / periodLength;
    // quarters are numbered 0..3

    int periodStartMonth = periodNr * periodLength + 1;
    // quarters start in months 1 / 4 / 7 / 10
    DateTime startPeriod = new DateTime(date.Year, periodStartMonth, 1);
    DateTime nextPeriod = startPeriod.AddMonths(periodLength);
    return new Period()
    {
        FirstDay = startPeriod,
        LastDay = nextPeriod.AddDays(-1),
    }
Expression<Func<Magazine, SupbscriptionPeriodType>> e1 = 
     magazine => magazine.SubscriptionPeriodType;
Expression<Func<SubscriptionPeriodType, int>> PeriodLength = s => (int)s;
Expression<Func<DateTime, int, int>> PeriodNr = 
    (date, periodLength) => (date.Month - 1) / periodLength;

// etc.
var result = dbContext.Magazines
    .Where(...)
    .Select(magazine => ConcatenatedExpression.... )