EF 代码优先 - IQueryable 具有特定小数的乘法 属性
EF code-first - IQueryable having multiplication on a specific decimal property
我一直在努力解决 Entity Framework 代码优先的以下问题。
我有一个带小数的实体 class,我有一个乘数小数参数。
我想构建一个查询(但不是调用它),其中 returns 个实体,但是 Bar
属性 需要与我的参数相乘。
编码方面:
public class Foo
{
public Guid Id { get; set; }
public Decimal Bar { get; set; }
}
// this simple stuff returns the entities after some filterings.
Context.Set<Foo>().Where(x => querying on many props).ToList();
这个方法和我想达到的效果类似:
public IQueryable<Foo> GetFooQuery( .. Many properties used to the query .. , Decimal Multiplier)
{
var IQueryablePart = Context.Set<Foo>().Where(querying with the parameters);
/* ... and what to do here? ... */
/* IQueryablePart = IQueryablePart.Select(x => new {
Bar = Bar * Multiplier <-- this is okay
}); */
// but how to retrieve the other columns without listing them one by one, and how to return the data as IQueryable<Foo> ?
return IQueryablePart;
}
我想按以下方式使用此方法:
IQueryable<Foo> FullQuery = null;
for(some loop, may be 10 or 1000 iterations, it depends) {
var Part = GetFooQuery(/* .. query params ..*/, 2);
if(MyFullQuery == null)
FullQuery = Part;
else
FullQuery.Union(Part);
}
// and in the end, do the db call once:
var Result = FullQuery.ToList();
在SQL中,我会这样处理:
SELECT
Id,
Bar * @MyValue as Bar,
# and all other columns
FROM
Foo
WHERE
(param queries 1) OR
(param queries 2) OR
---
(param queries N)
我的问题是:通过 IQueryable
和 EF 执行此操作的方法是什么?最重要的是,我只需要调用一次数据库。
我想这可能是一些查询构建的东西,但我还不熟悉它,任何帮助将不胜感激。
EF6 不支持投影 (select
) 到映射为实体的 class。因此,您唯一的选择是投射到一些匿名或特殊的 class。对于您的场景,我看到的最简单的是 class 这样的:
public class FooBar
{
public Foo Foo { get; set; }
public decimal Bar { get; set; }
}
那么单条查询方式可以是这样的:
public IQueryable<FooBar> GetFooQuery( .. Many properties used to the query .. , decimal multiplier)
{
return Context.Set<Foo>()
.Where(querying with the parameters)
.Select(foo => new FooBar
{
Foo = foo,
Bar = foo.Bar * multiplier
});
}
现在您可以构建完整的查询:
IQueryable<FooBar> fullQuery = null;
for (some loop, may be 10 or 1000 iterations, it depends)
{
var subQuery = GetFooQuery(/* .. query params ..*/, 2);
fullQuery = fullQuery == null ? subquery : fullQuery.Union(subQuery);
}
注意,如果你使用不同的乘法器(否则整个过程没有意义),你最好使用LINQ Concat
方法(转换为SQL UNION ALL
)而不是 Union
(转换为 SQL UNION
)。
最后,您可以通过执行单个最终 SQL 查询将结果具体化为 Foo
序列,切换到 LINQ to Objects 并将 FooBar
转换为 Foo
像这样:
var result = fullQuery.
.AsEnumerable() // db query ends here
.Select(fooBar =>
{
fooBar.Foo.Bar = fooBar.Bar;
return fooBar.Foo;
})
.ToList();
我一直在努力解决 Entity Framework 代码优先的以下问题。
我有一个带小数的实体 class,我有一个乘数小数参数。
我想构建一个查询(但不是调用它),其中 returns 个实体,但是 Bar
属性 需要与我的参数相乘。
编码方面:
public class Foo
{
public Guid Id { get; set; }
public Decimal Bar { get; set; }
}
// this simple stuff returns the entities after some filterings.
Context.Set<Foo>().Where(x => querying on many props).ToList();
这个方法和我想达到的效果类似:
public IQueryable<Foo> GetFooQuery( .. Many properties used to the query .. , Decimal Multiplier)
{
var IQueryablePart = Context.Set<Foo>().Where(querying with the parameters);
/* ... and what to do here? ... */
/* IQueryablePart = IQueryablePart.Select(x => new {
Bar = Bar * Multiplier <-- this is okay
}); */
// but how to retrieve the other columns without listing them one by one, and how to return the data as IQueryable<Foo> ?
return IQueryablePart;
}
我想按以下方式使用此方法:
IQueryable<Foo> FullQuery = null;
for(some loop, may be 10 or 1000 iterations, it depends) {
var Part = GetFooQuery(/* .. query params ..*/, 2);
if(MyFullQuery == null)
FullQuery = Part;
else
FullQuery.Union(Part);
}
// and in the end, do the db call once:
var Result = FullQuery.ToList();
在SQL中,我会这样处理:
SELECT
Id,
Bar * @MyValue as Bar,
# and all other columns
FROM
Foo
WHERE
(param queries 1) OR
(param queries 2) OR
---
(param queries N)
我的问题是:通过 IQueryable
和 EF 执行此操作的方法是什么?最重要的是,我只需要调用一次数据库。
我想这可能是一些查询构建的东西,但我还不熟悉它,任何帮助将不胜感激。
EF6 不支持投影 (select
) 到映射为实体的 class。因此,您唯一的选择是投射到一些匿名或特殊的 class。对于您的场景,我看到的最简单的是 class 这样的:
public class FooBar
{
public Foo Foo { get; set; }
public decimal Bar { get; set; }
}
那么单条查询方式可以是这样的:
public IQueryable<FooBar> GetFooQuery( .. Many properties used to the query .. , decimal multiplier)
{
return Context.Set<Foo>()
.Where(querying with the parameters)
.Select(foo => new FooBar
{
Foo = foo,
Bar = foo.Bar * multiplier
});
}
现在您可以构建完整的查询:
IQueryable<FooBar> fullQuery = null;
for (some loop, may be 10 or 1000 iterations, it depends)
{
var subQuery = GetFooQuery(/* .. query params ..*/, 2);
fullQuery = fullQuery == null ? subquery : fullQuery.Union(subQuery);
}
注意,如果你使用不同的乘法器(否则整个过程没有意义),你最好使用LINQ Concat
方法(转换为SQL UNION ALL
)而不是 Union
(转换为 SQL UNION
)。
最后,您可以通过执行单个最终 SQL 查询将结果具体化为 Foo
序列,切换到 LINQ to Objects 并将 FooBar
转换为 Foo
像这样:
var result = fullQuery.
.AsEnumerable() // db query ends here
.Select(fooBar =>
{
fooBar.Foo.Bar = fooBar.Bar;
return fooBar.Foo;
})
.ToList();