Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Get Difference between Following Entities Linq to Entities

Summing up the problem in a single line for clarity as suggested:

I want to find all the things that have different values for some field and are less than a week apart (based on another field)


Let's say I have a Users table and a User class.

Each User has the following fields:

  • SignUpDate a non-null DateTime field
  • UserType an int field, for this question let's say it's either 1 or 0

I'd like to select all the couples of users that signed up less than 7 days apart and have a different user type.

My current (miserable) attempt included an OrderBy(r=>r.SignUpDate) and a .ToList which wasn't a big deal since the number of users for every 2 weeks is not large. (I grabbed all the users from that with overlapping weeks and compared the data).

However, I find my current solution pretty poor. I have no idea what's the correct way to approach this.

I think the core problem here is that I don't know how to address the concept of 'selecting every two corresponding records' in LINQ to Entities after an ordering.

Any help much appreciated, I'm interested in how I would be able to solve this sort of problem without starting my own question in the future.

Example input

 SignUpDate        UserType
 ------------------------------------
 2008-11-11          1
 2008-11-12          0
 2008-11-13          0
 2008-12-13          0
 2008-12-15          1

Example output

Any meaningful way to indicate that the problematic pairs were:

 2008-11-11          1
 2008-11-12          0

(Different by a day and different type)

And

 2008-12-13          0
 2008-12-15          1

(Different by two days and different type)


Here is a related SQL solution I found.

like image 248
Benjamin Gruenbaum Avatar asked Oct 21 '22 08:10

Benjamin Gruenbaum


1 Answers

I don't fully understand what problem you are trying to solve, so the following will be general recommendations only. It sounds like any two user sign-ups that are "adjacent in time" and within a week from each other is the rule, but it sounds a bit odd..

Whenever you want to query on a piece of information that is only indirectly available (i.e. something that is not simple a column value), use a projection to select the information you need to solve the problem.

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 )
            };

Once you have the data in a more accessible format, it becomes much easier to write the query to solve the business problem.

var duplicates = (from d in query
                 where d.IsDuplicate && d.SignUpDaysApart.TotalDays <= 7
                 select d).ToList();

I hope the above is inspiration enough for you to arrive at a solution.

like image 122
Morten Mertner Avatar answered Oct 24 '22 02:10

Morten Mertner