2

I have an AlbumArtist class (which is my EF Entity):

public class AlbumArtist : IEquatable<AlbumArtist>
{
    public int Id { get; set; }

    public string Title { get; set; }

    public virtual List<Album> Albums { get; set; }

    public bool Equals(AlbumArtist albumArtist)
    {
        return Title.Equals(albumArtist.Title);
    }

    public override int GetHashCode()
    {
        return Title.GetHashCode();
    }
}

And an Album class (which is my EF Entity too):

public class Album : IEquatable<Album>
{
    public int Id { get; set; }

    public string Title { get; set; }

    public virtual List<AlbumArtist> AlbumArtists { get; set; }

    public bool Equals(Album album)
    {
        return Title.Equals(album.Title);
    }

    public override int GetHashCode()
    {
        return Title.GetHashCode();
    }
}

So, as you see, I have many-to-many relationship.

I create one list, populate it, than save it with DbContext, then I create and populate the second list. And then I try to merge that two lists (one from DbContext, second from the local variable) and save the result to DbContext as well (insert new entities and update existing).

I have the following data in my two lists:

--Infected Mushroom
----Classical Mushroom
----Converting Vegetarians
...



--Infected Mushroom
----The Gathering ‎
----Converting Vegetarians
--Skazi
...

And I try to get the following data:

--Infected Mushroom
----Classical Mushroom
----The Gathering ‎
----Converting Vegetarians
--Skazi
...

Please help me to write some LINQ query to achieve my goal.

Thanks!


I decided to take the plunge, given my previous warnings about reliance upon the client's time, and write a pure JavaScript version:

var timeList = [
    { 'days': [0,1,2,3,4], 'times': [ [ 10, 18 ], [12, 30] ] },
    { 'days': [5,6], 'times': [ [ 10,30 ], [12, 30] ] }
];

var minutesNearTimeListToShow = 30;
var pollSeconds = 60;

$(document).ready(function() {
    checkForShowing();
});

function checkForShowing() {

    var now = new Date();
    var currentDay = now.getDay();
    var currentHour = now.getHours();
    var currentMinute = now.getMinutes();
    var timeAndDay = getNextTimeAndDay (currentDay, currentHour, currentMinute);

    var nextAlertDue = new Date(now.getYear() + 1900, now.getMonth(), now.getDate(), timeAndDay.hour, timeAndDay.minute);
    nextAlertDue.setDate(now.getDate() - currentDay + timeAndDay.day);

    var differenceSeconds = (nextAlertDue - now) / 1000;

    if (differenceSeconds < minutesNearTimeListToShow * 60) {

        $(".myButton").show();
        window.setTimeout (function() {
            $(".myButton").hide();
        }, differenceSeconds * 1000);

    } else {
        $(".myButton").hide();
        window.setTimeout(checkForShowing, pollSeconds * 1000);
    }

}

function getNextTimeAndDay(tDay, tHour, tMinute) {

    var times = getTimesForDay(tDay);
    var nextTime = getNextTime (tHour, tMinute, times)

    if (!nextTime) {
        tHour = 0;
        tMinute = 0;        
        tDay++;
        if (tDay == 7) { tDay = 0; }
        times = getTimesForDay(tDay);
        nextTime = getNextTime (tHour, tMinute, times);
    }

    return { day: tDay, hour: nextTime[0], minute: nextTime[1] };

}

function getNextTime (tHour, tMinute, times) {

    for (var i in times) {
        if ((tHour < times[i][0]) || (tHour == times[i][0] && tMinute <= times[i][1])) {
            return times[i];
        }
    }

    return false;

}

function getTimesForDay(currentDay) {

    var times = false;

    for (var i in timeList) {
        var days = timeList[i].days;
        if (days.indexOf(currentDay) > -1) {
            times =  timeList[i].times;
        }
    }

    return times;

}

The main configuration is right at the top, allowing different times to be specified for different days.

Once a minute, the code will check to see if it is within half an hour of one of these times; if it is, then the button will be shown and a setTimeout set up to hide it again (and restart polling) when the half-hour is up.

Note that if the code starts within the half-hour (e.g. 20 minutes in), it will pick up on that, show the button, and schedule the hiding for just 10 minutes later.

The date checking is reasonably well tested, the scheduling not so much - feel free to suggest corrections!

4

2 回答 2

2

SelectMany借助函数,可以使用 LINQ 。

你可以找到SelectMany 这里的例子

于 2013-09-05T11:34:51.900 回答
0

您可以使用 LINQ 运算符JoinUnion. 为了证明这一点,我将您的问题简化为两个字符串组列表:

var list1 = new[] {
    Tuple.Create("Infected Mushroom", "Classical Mushroom"),
    Tuple.Create("Infected Mushroom", "Converting Vegetarians"),
    Tuple.Create("Skazi", "Animal")
}
.GroupBy(t => t.Item1, t => t.Item2);
var list2 = new[] {
    Tuple.Create("Infected Mushroom", "The Gathering"),
    Tuple.Create("Skazi", "Animal")
}
.GroupBy(t => t.Item1, t => t.Item2);

每个列表中的每个项目都是艺术家IGrouping所在的位置,其中的元素是专辑。KeyIGrouping

然后,您可以使用以下方法组合这两个列表Join

var combinedList = list1.Join(
  list2,
  g1 => g1.Key,
  g2 => g2.Key,
  (g1, g2) => new { Artist = g1.Key, Albums = g1.Union(g2) }
);

匹配g1.Keyg2.Key确保元素与艺术家匹配。然后为每个艺术家创建专辑g1.Union(g2)

于 2013-09-05T12:05:25.533 回答