Linq-to-SQL Help - Выбор дублирующихся строк - PullRequest
3 голосов
/ 09 июля 2010

Вот что я пытаюсь сделать:

select subscriber, count(subscriber)
from subscribers
where subscriber = subscribedTo
group by subscriber
having count(subscriber) > 1

Достаточно просто в SQL.Я не могу понять, как написать это в LINQ.Кто-нибудь знает, как это сделать?

В таблице всего три столбца, идентификатор, подписчик и подписано.Я пытаюсь найти повторяющиеся строки, где подписчик == subscribedTo.

Ответы [ 3 ]

4 голосов
/ 09 июля 2010

Вы можете попробовать это

var duplicatedSubscribers= 
    from s in subscribers 
    where s.subscribedTo == s.subscriber 
    group s by s.subscriber into g 
    where g.Count() > 1 
    select new { subscriber = g.Key, Count = g.Count() };

Вы можете проверить образцы LINQ в http://msdn.microsoft.com/en-us/vcsharp/aa336746.aspx

0 голосов
/ 09 июля 2010

Вы можете использовать синтаксис запроса или методы расширения. Я приведу примеры в обоих. Вы можете перемещать ГДЕ фильтрацию обычно. Я решил держать его отдельно, чтобы вы могли немного поиграть с кодом и увидеть разницу в группировке. В Linq To SQL лучше будет переводить в SQL, если вы переместите условия WHERE в выражение с группировкой.

Ваша сущность, вероятно, выглядит следующим образом.

    public class CustomRowType
    {
        public int ID { get; set;}
        public string Subscriber { get; set; }
        public int SubscribedTo { get; set; }
    }

Во-первых, пример использования методов расширения. Так я обычно предпочитаю.

    public void GroupTest()
    {
        // Create some data to work with.
        List<CustomRowType> testData = new List<CustomRowType>();
        testData.Add(new CustomRowType() { ID = 1, Subscriber = "Subscriber 1", SubscribedTo = 40 });
        testData.Add(new CustomRowType() { ID = 2, Subscriber = "Subscriber 2", SubscribedTo = 1 });
        testData.Add(new CustomRowType() { ID = 3, Subscriber = "Subscriber 3", SubscribedTo = 2 });
        testData.Add(new CustomRowType() { ID = 4, Subscriber = "Subscriber 4", SubscribedTo = 2 });

        // Group data (equivalent to GROUP BY clause)
        var grp = testData.GroupBy(
            row => row.SubscribedTo,
            (key, row) => new
            {
                Data = row,
                // Here is the aggregate value
                KeyCount = testData.Count(i => i.SubscribedTo == key)   
            }
        );

        var output = grp
            // Filter group data (equivilent to HAVING clause)
            .Where(g => g.KeyCount > 1) // Remove this line to see all aggregate data.
            // Flatten group data (equivalent to SELECT clause)
            .SelectMany(g => g.Data
                .Select(d => d.ID.ToString() + "(" + d.Subscriber + ") -> " + d.SubscribedTo.ToString()+" with (" + g.KeyCount.ToString() + ") total subscriptions" ))
            .ToList();

        listBox1.Items.Clear();
        output.ForEach(s => listBox1.Items.Add(s));

    }

Далее приведен пример синтаксиса запроса.

public void GroupTest()
        {
            // Create some data to work with.
            List<CustomRowType> testData = new List<CustomRowType>();
            testData.Add(new CustomRowType() { ID = 1, Subscriber = "Subscriber 1", SubscribedTo = 40 });
            testData.Add(new CustomRowType() { ID = 2, Subscriber = "Subscriber 2", SubscribedTo = 1 });
            testData.Add(new CustomRowType() { ID = 3, Subscriber = "Subscriber 3", SubscribedTo = 2 });
            testData.Add(new CustomRowType() { ID = 4, Subscriber = "Subscriber 4", SubscribedTo = 2 });


            // Using query syntax
            var grp = (
                from d in testData
                group d by d.SubscribedTo into g
                select g
            );


            var output = grp
                // Filter
                .Where(g => g.Count() > 1)
                // Flatten group data (equivalent to SELECT clause)
                .SelectMany(g => g
                    .Select(d => d.ID.ToString() + "(" + d.Subscriber + ") -> " + d.SubscribedTo.ToString()+" with (" + g.Key.ToString() + ") total subscriptions" ))
                .ToList();

            listBox1.Items.Clear();
            output.ForEach(s => listBox1.Items.Add(s));

        }
0 голосов
/ 09 июля 2010

Пожалуйста, посмотрите мой ответ:

public  class MyClass
    {

        public int ID
        {
            get; set;
        }

        public string Subscriber
        {
            get; set;
        }

        public string SubscriberTo
        {
            get; set;
        }
    }

И код для перечисления списка моего класса:

   var myList = new List<MyClass>();

            var douplicateRows = from element in myList
                                              where
                                                  string.Compare(element.Subscriber, element.SubscriberTo,
                                                                 StringComparison.InvariantCultureIgnoreCase) == 0
                                              group element by element.Subscriber
                                              into mygroup
                                              where mygroup.Count() > 1
                                              select new
                                                         {
                                                             Subscriber = mygroup.Key,
                                                             Elements= mygroup
                                                         };

Надеюсь, эта помощь.

...