在Entity Framework 6中,我可以使用SqlFunctions.DatePart()
方法:
var byWeek = data.GroupBy(x => SqlFunctions.DatePart("week", x.Date));
但是这些类(DbFunctions
和SqlFunctions
在实体框架核心中不可用)(reference)。
所以我的问题是如何在Entity Framework核心中按周分组?
答案 0 :(得分:3)
我目前缺少功能的解决方法是
var firstMondayOfYear = this.GetFirstMondayOfYear(DateTime.Now.Year);
var entries =
this.entitiesService.FindForLastMonths(this.CurrentUser.Id, 6)
.GroupBy(x => ((int)(x.Date - firstMondayOfYear).TotalDays / 7))
函数GetFirstMondayOfYear
:
private DateTime GetFirstMondayOfYear(int year)
{
var dt = new DateTime(year, 1, 1);
while (dt.DayOfWeek != DayOfWeek.Monday)
{
dt = dt.AddDays(1);
}
return dt;
}
此分组给出当前年份的周数和前几年的负值。
稍后您可以使用此getter获取周名称:
public string WeekName
{
get
{
var year = DateTime.Now.AddYears((int)Math.Floor(this.WeekNumber / 52.0)).Year;
var weekNumber = this.WeekNumber % 52;
while (weekNumber < 0)
{
weekNumber += 52;
}
return $"{year}, W{weekNumber}";
}
}
答案 1 :(得分:1)
可以通过将日期部分SQL函数与DbFunctionAttribute包装在一起来使用它。 棘手的部分是告诉ef核心不要将datepart类型参数作为字符串处理。示例:
DbContext:
class Nav extends Component {
constructor(props){
super(props);
["showHideSubmenu"].forEach((method) => {
this[method] = this[method].bind(this);
});
this.state = {
navigation: {
menu: [],
},
showSubmenu: -1,
}
}
componentDidMount() {
fetch('http:json_menuFIN.php')
.then(response => response.json())
.then(data =>{
this.setState({navigation: data});
})
}
showHideSubmenu(key){
this.setState({
showSubmenu: key,
});
}
render(){
const renderMenu = items => {
return (
<ul className="list">
{items.map((i, key) => {
var icoJson;
if(i.ico){
icoJson = <Icon icon={i.ico} className={"ico-" + i.ico} />;
}
var firstMenu = i.fstmenu ? "first-menu" : "";
var secondMenu = i.sndmenu ? "second-menu" : "";
var classMn = i.fstmenu ? "mn-" : "";
var classSb = i.sndmenu ? "sb-" : "";
return (
<li className={`list__item ${firstMenu}${secondMenu}`} key={i.fsttitle + i.sndtitle + i.trdtitle}>
<a
href={i.URL}
className={`${classMn}${classSb}`+i.fsttitle}
onClick={(key) => {
if (i.fstmenu) {
this.showHideSubmenu(key);
}
}
>
{icoJson}
<span>{i.fsttitle}{i.sndtitle}{i.trdtitle}</span>
</a>
{i.menu && renderMenu(i.menu)}
{this.state.showSubmenu === key &&
(
<>
{i.fstmenu && renderMenu(i.fstmenu)}
{i.sndmenu && renderMenu(i.sndmenu)}
</>
)
}
</li>
)
})}
</ul>
)
}
return (
<nav className="nav">
<div className="menu">
{renderMenu(this.state.navigation.menu)}
</div>
</nav>
)
}
}
查询:
public int? DatePart(string datePartArg, DateTime? date) => throw new Exception();
public void OnModelCreating(DbModelBuilder modelBuilder) {
var methodInfo = typeof(DbContext).GetRuntimeMethod(nameof(DatePart), new[] { typeof(string), typeof(DateTime) });
modelBuilder
.HasDbFunction(methodInfo)
.HasTranslation(args => new SqlFunctionExpression(nameof(DatePart), typeof(int?), new[]
{
new SqlFragmentExpression(args.ToArray()[0].ToString()),
args.ToArray()[1]
}));
}
更多信息:https://github.com/aspnet/EntityFrameworkCore/issues/10404
答案 2 :(得分:0)
我碰巧已经在使用一个视图,因此我只是在该视图中添加了代表星期,月份和年份的额外列,以便通过EF Core轻松分组。
OrderDateDt,
DATEPART(week, OrderDateDt) OrderDateDt_Week,
DATEPART(month, OrderDateDt) OrderDateDt_Month,
DATEPART(year, OrderDateDt) OrderDateDt_Year,