我正在尝试在整个项目中删除重复的代码,但我一直处于停滞状态,试图找出答案。我正在尝试做的是创建一个基本的linq查询,该查询将被重用于以多种不同的方法添加诸如Where,Take ...等内容。
const allData = _.range(0, 10, 0.001).map(x => ({
x: x,
y: Math.sin(Math.PI*x/2) * x / 10
}));
class CustomChart extends React.Component {
constructor(props) {
super();
this.entireDomain = this.getEntireDomain(props);
this.state = {
zoomedXDomain: this.entireDomain.x,
};
}
onDomainChange(domain) {
this.setState({
zoomedXDomain: domain.x,
});
}
getData() {
const { zoomedXDomain } = this.state;
const { data, maxPoints } = this.props;
const filtered = data.filter(
(d) => (d.x >= zoomedXDomain[0] && d.x <= zoomedXDomain[1]));
if (filtered.length > maxPoints ) {
const k = Math.ceil(filtered.length / maxPoints);
return filtered.filter(
(d, i) => ((i % k) === 0)
);
}
return filtered;
}
getEntireDomain(props) {
const { data } = props;
return {
y: [_.minBy(data, d => d.y).y, _.maxBy(data, d => d.y).y],
x: [ data[0].x, _.last(data).x ]
};
}
getZoomFactor() {
const { zoomedXDomain } = this.state;
const factor = 10 / (zoomedXDomain[1] - zoomedXDomain[0]);
return _.round(factor, factor < 3 ? 1 : 0);
}
render() {
const renderedData = this.getData();
return (
<div>
<VictoryChart
domain={this.entireDomain}
containerComponent={<VictoryZoomContainer
zoomDimension="x"
zoomDomain={this.state.zoomedXDomain}
onZoomDomainChange={this.onDomainChange.bind(this)}
minimumZoom={{x: 1/10000}}
/>}
>
<VictoryScatter data={renderedData} />
</VictoryChart>
<VictoryChart
domain={this.entireDomain}
containerComponent={<VictoryZoomContainer
zoomDimension="x"
zoomDomain={this.state.zoomedXDomain}
onZoomDomainChange={this.onDomainChange.bind(this)}
minimumZoom={{x: 1/10000}}
/>}
>
<VictoryScatter data={renderedData} />
</VictoryChart>
<div>
{this.getZoomFactor()}x zoom;
rendering {renderedData.length} of {this.props.data.length}
</div>
</div>
);
}
}
ReactDOM.render(<CustomChart data={allData} maxPoints={120} />, mountNode);
所以这将通过上面的基本查询进行,我将有一个单独的方法来重用VioLinq,但是这次将在其中使用where子句。
public IQueryable<Object> FooLinq(int id)
{
using (var ctx = new dbEntities())
{
var results =
(from account in ctx.account
join memberProducts in ctx.tblMemberProducts on account.Id equals memberProducts.AccountId
orderby account.date descending
select new{account,memberProducts}).ToList();
return results;
}
}
答案 0 :(得分:1)
您需要做两件事:
这两个要求会互相抵消,可以采用多种方法来满足它们。
例如,您可以使您的方法将上下文作为参数,从而迫使调用者提供它并管理其生命周期。
public IQueryable<AccountInfo> FooLinq(DbEntities ctx, int id)
{
return
from account in ctx.account
orderby account.date descending
select new AccountInfo()
{
Name = account.Name,
Mid = account.MemberID,
Date = account.Date,
Address = account.Address,
};
}
public List<IncomingViolations> Foo1(int id)
{
using(var ctx = new dbEntities())
{
//Linq query FooLinq() where Name == "Bob"
return FooLinq(ctx).Where(v => v.Name == "Bob").ToList();
}
}
您也可以将上下文作为构造函数注入的依赖项注入,并使用DI框架来管理上下文的生命周期。
答案 1 :(得分:0)
您可以将其作为Queryable进行添加,然后为其添加条件。 例如:
public List<account> GetAccountsByName(string name, bool usePaging, int offset = 0, int take = 0) {
var query = GetMyQuery();
query = query.Where(x => x.Name == name);
query = query.OrderBy(x => x.Name);
if(usePaging) {
query = query.Take(take).Skip(offset);
}
query = PrepareSelectForAccount(query);
return query.ToList(); .
}
public IQueryable<account> GetMyQuery(){
return ctx.account.AsQueryable();
}
public IQueryable<account> PrepareSelectForAccount(IQueryAble<account> query){
return query.Select(select new AccountInfo()
{
Name = account.Name,
Mid = account.MemberID,
Date = account.Date,
Address = account.Address,
}
);
}
答案 2 :(得分:-1)
可以,但是不要调用>=4
,而是返回.ToList()
而不是IQueryable<T>
。 LINQ基于deferred execution的概念,这意味着直到对可枚举进行迭代之前,查询才真正执行。在此之前,您所要做的只是建立一个对象,该对象知道在时间到了时如何进行查询。
通过从设置“基本查询”的函数返回List<T>
,然后可以随意使用其他LINQ方法(例如IQueryable<T>
或.Where()
)来生成修改后的查询。至此,您仍在简单地设置查询。实际上,只有在您遍历可枚举或调用类似.Take()
之类的操作时,它才会执行。