Как разрешить множественное объединение с LinQ? - PullRequest
0 голосов
/ 06 марта 2020

Итак, допустим, у меня есть Contest, который может иметь несколько ContestCulture. Для этого конкурса у меня должно быть Documents, которое имеет DocumentType и Culture (Правила, Условия и Условия, PrivacyPolicy)

Для каждого ContestCulture, я должен иметь, КАК минимум, один Document для каждого DocumentType для того, чтобы Contest был действительным.

Итак, скажем, у меня есть Contest с 2 ContestCulture (fr-CA, en-CA), который я должен иметь по крайней мере 6 Document для этого Contest

  • Документ1: Культура1, Правила
  • Документ2: Культура1, Условия и Условия
  • Документ3: Культура1, PrivacyPolicy
  • Document4: Culture2, Rules
  • Document5: Culture2, TermsAndConditions
  • Document6: Culture2, PrivacyPolicy

Сущности похожи на следующие:

public class Document
{
    public DocumentType DocumentType { get; set; }
    public int CultureId { get; set; }
    public Culture Culture { get; set; }
    public int ContestId { get; set; }
    public Contest Contest { get; set; }
    //Some other properties
    //...
}

public class Contest
{
    public List<Document> Documents { get; set; }
    public List<ContestCulture> ContestCultures { get; set; }
    //Some other properties
    //...

}

public class ContestCulture 
{
     public int ContestId { get; set; }
    public Contest Contest { get; set; }

    public int CultureId { get; set; }
    public Culture Culture { get; set; }

    //Some other properties
    //...
}

public class Culture
{
    public string Code { get; set; }
    public string Name { get; set; }
}

Теперь, когда контекст установлен ..

У меня есть 3 списка:

  • список DocumentType (список enum значений)
  • a список ContestCulture идентификаторов (список int)
  • список Documents для Contest (список Document)

Как проверить если у меня есть хотя бы 1 Document fo r каждый DocumentType для каждого ContestCulture?

Я действительно новичок в LinQ, поэтому я попробовал это:

from cultureId in list_usedCultureIdsForContest
join doc in documents on cultureId equals doc.CultureId into temp1
from t in temp1.DefaultIfEmpty()
select new {cultureId, t};

, но он дает мне только те, которые у меня есть, как показано ниже: enter image description here

Ответы [ 2 ]

1 голос
/ 06 марта 2020

Сначала получите необходимое количество типов документов для каждой культуры из enum:

var numDocumentTypes = Enum.GetNames(typeof(DocumentType)).Length;

Затем подсчитайте количество различных типов документов для каждого CultureId:

var docTypesPerCulture = documents.GroupBy(d => d.CultureId)
                                  .Select(dg => new {
                                        CultureId = dg.Key,
                                        Count = dg.Select(d => d.DocumentType).Distinct().Count()
                                   });

Теперь вы можете присоединиться к использованным идентификаторам культур (чтобы обрабатывать идентификаторы культур, у которых нет документов) и отфильтровать их с отсутствующими типами документов:

var ans = list_usedCultureIdsForContest.GroupJoin(docTypesPerCulture,
                                                  ci => ci,
                                                  dpc => dpc.CultureId,
                                                  (ci, dpcj) => dpcj.Any() ? dpcj.Select(dpc => new { CultureId = ci, Count = dpc.Count }).Single()
                                                                           : new { CultureId = ci, Count = 0 }
                                        )
                                       .Where(cic => cic.Count != numDocumentTypes);
0 голосов
/ 06 марта 2020

Простой:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApplication159
{
    class Program
    {

        static void Main(string[] args)
        {
            List<Document> contest = new List<Document>() {
                new Document() { contestCulture = 1,  documentType = DocumentType.Rules },
                new Document() { contestCulture = 1,  documentType = DocumentType.TermsAndConditions },
                new Document() { contestCulture = 1,  documentType = DocumentType.PrivacyPolicy },
                new Document() { contestCulture = 2,  documentType = DocumentType.Rules },
                new Document() { contestCulture = 2,  documentType = DocumentType.TermsAndConditions },
                new Document() { contestCulture = 2,  documentType = DocumentType.PrivacyPolicy  }
            };

            var valid = contest.GroupBy(x => x.contestCulture)
                .Select(x => new { culture = x.Key, valid = Valid(x.ToList()) })
                .ToList();


        }

        static bool Valid(List<Document> documents)
        {
            return documents.Any(x => x.documentType == DocumentType.Rules) &&
                documents.Any(x => x.documentType == DocumentType.TermsAndConditions) &&
                documents.Any(x => x.documentType == DocumentType.PrivacyPolicy);
        }
    }
    public enum DocumentType
    {
        Rules,
        TermsAndConditions,
        PrivacyPolicy
    }
    public class Document
    {
        public int contestCulture { get; set; }
        public DocumentType documentType { get; set; }
    }

}

И еще один способ

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApplication159
{
    class Program
    {

        static void Main(string[] args)
        {
            List<Document> contest = new List<Document>() {
                new Document() { contestCulture = 1,  documentType = DocumentType.Rules },
                new Document() { contestCulture = 1,  documentType = DocumentType.TermsAndConditions },
                new Document() { contestCulture = 1,  documentType = DocumentType.PrivacyPolicy },
                new Document() { contestCulture = 2,  documentType = DocumentType.Rules },
                new Document() { contestCulture = 2,  documentType = DocumentType.TermsAndConditions },
                new Document() { contestCulture = 2,  documentType = DocumentType.PrivacyPolicy  }
            };

            var valid = contest.GroupBy(x => x.contestCulture)
                .Select(x => new { culture = x.Key, valid = Valid(x.ToList()) })
                .ToList();

        }

        static bool Valid(List<Document> documents)
        {
            int or = 0;
            foreach (Document document in documents)
            {
                or |= (int)document.documentType;
            }
            return (or == 7) ? true : false;
        }
    }
    public enum DocumentType
    {
        Rules = 1,
        TermsAndConditions = 2,
        PrivacyPolicy = 4
    }
    public class Document
    {
        public int contestCulture { get; set; }
        public DocumentType documentType { get; set; }
    }

}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...