为了清晰起见,将问题总结为一行:
假设我有一个Users
表和一个User
类。
每个User
都有以下字段:
SignUpDate
非空DateTime
字段UserType
一个int字段,对于这个问题,我们可以说它是1
或0
我想选择所有注册时间不到7天且用户类型不同的用户。
我当前(悲惨)的尝试包括OrderBy(r=>r.SignUpDate)
和.ToList
,这并不是什么大问题,因为每2周的用户数量并不大。 (我抓住所有用户,重复周数并比较数据)。
但是,我觉得我目前的解决方案很差。我不知道接近这个的正确方法是什么。
我认为这里的核心问题是我不知道如何在订购后解决“在LINQ to Entities 中选择每两个相应记录”的概念。
任何帮助都非常感谢,我很感兴趣我将来能够解决这类问题,而不会在未来开始我自己的问题。
SignUpDate UserType
------------------------------------
2008-11-11 1
2008-11-12 0
2008-11-13 0
2008-12-13 0
2008-12-15 1
任何有意义的方式表明问题对是:
2008-11-11 1
2008-11-12 0
(每天不同,不同类型)
并且
2008-12-13 0
2008-12-15 1
(两天不同,不同类型)
这是我发现的related SQL solution。
答案 0 :(得分:3)
我不完全明白您要解决的问题,因此以下仅为一般性建议。这听起来像是任何两个用户注册时间相邻的#34;并且在一个星期内彼此是规则,但听起来有点奇怪..
每当您想要查询仅间接可用的信息时(即列值不简单的信息),请使用投影选择解决问题所需的信息。
var query = from user in context.Users
let previousUser = context.Users
.Where( u => u.SignUpDate < user.SignUpDate )
.OrderBy( u => u.SignUpDate )
.FirstOrDefault()
select new
{
User = user,
PreviousUser = previousUser,
IsDuplicate = previousUser != null && previousUser.UserType != user.UserType,
SignUpDaysApart = user.SignUpDate.Subtract( previousUser.SignUpDate )
};
以更易于访问的格式获取数据后,编写查询以解决业务问题变得更加容易。
var duplicates = (from d in query
where d.IsDuplicate && d.SignUpDaysApart.TotalDays <= 7
select d).ToList();
我希望上述内容足以让您找到解决方案。
答案 1 :(得分:0)
想到这样......
private bool LessThan7DaysApart(DateTime d1, DateTime d2)
{
return (d1 - d2).Duration() < new TimeSpan(7, 0, 0, 0);
}
private void Match()
{
List<User> listfortype0 = users.Where(u => u.UserType == 0).ToList();
List<User> listfortype1 = users.Where(u => u.UserType == 1).ToList();
foreach (User u in listfortype0)
{
List<User> tmp = listfortype1.Where(u2 => LessThan7DaysApart(u2.SignUpDate, u2.SignUpDate)).ToList();
if (tmp.Count > 0)
{
List<User> matchedusers = new List<User> { u, tmp[0] };
listfortype1.Remove(tmp[0]);
}
}
}