기본 엔티티의 공통 식별자를 기반으로 관련 엔티티 필터링

niklr

기본 엔터티의 공통 식별자로 엔터티 목록을 그룹화하고 각 그룹의 첫 번째 엔터티를 선택한 다음 새 엔터티 목록을 반환하고 싶습니다. 관련된 세 가지 엔터티가 있습니다 : GenericObject, ObjectVersion 및 ObjectDependency.

public class GenericObject
{
    public int Id { get; set; }
}

public class ObjectVersion
{
    public int Id { get; set; }
    public GenericObject GenericObject { get; set; }
}

public class ObjectDependency
{
    public string Name { get; set; }
    public ObjectVersion ObjectVersion1 { get; set; }
    public ObjectVersion ObjectVersion2 { get; set; }
}

샘플 설정은 다음과 같습니다.

GenericObject go1 = new GenericObject { Id = 1 };
GenericObject go2 = new GenericObject { Id = 2 };
GenericObject go3 = new GenericObject { Id = 3 };

ObjectVersion ov1 = new ObjectVersion { Id = 1, GenericObject = go1 };
ObjectVersion ov2 = new ObjectVersion { Id = 2, GenericObject = go2 };
ObjectVersion ov3 = new ObjectVersion { Id = 3, GenericObject = go3 };
ObjectVersion ov4 = new ObjectVersion { Id = 4, GenericObject = go1 };

List<ObjectDependency> dependencies = new List<ObjectDependency>
{
     new ObjectDependency { Name = "d1", ObjectVersion1 = ov1, ObjectVersion2 = ov2 },
     new ObjectDependency { Name = "d2", ObjectVersion1 = ov2, ObjectVersion2 = ov3 },
     new ObjectDependency { Name = "d3", ObjectVersion1 = ov4, ObjectVersion2 = ov2 }
};

ov2를 포함하는 모든 ObjectDependencies를 얻으려면 다음과 같이 필터링합니다.

var ov2Dependencies = dependencies.Where(d => d.ObjectVersion1.Id == ov2.Id 
                                              || d.ObjectVersion2.Id == ov2.Id)
                                  .OrderBy(d => d.Name);
foreach (ObjectDependency dependency in ov2Dependencies)
{
    Console.WriteLine(dependency.Name);
}
// Output:
// d1
// d2
// d3

ov2에 종속 된 모든 ObjectVersion을 얻으려면 :

var ov2AllDependentObjectVersions = 
             dependencies.Where(d => d.ObjectVersion1.Id == ov2.Id 
                                     || d.ObjectVersion2.Id == ov2.Id)
                         .Select(d => d.ObjectVersion1)
                         .Union(dependencies.Where(d => d.ObjectVersion1.Id == ov2.Id 
                                                       || d.ObjectVersion2.Id == ov2.Id)
                         .Select(d => d.ObjectVersion2))
                         .Where(o => o.Id != ov2.Id)
                         .OrderBy(o => o.Id);
foreach (ObjectVersion ov in ov2AllDependentObjectVersions)
{
    Console.WriteLine(ov.Id);
}
// Output:
// 1
// 3
// 4

GenericObject가 다른 ov2에 종속 된 최신 ObjectVersion을 얻으려면 :

var ov2LatestDependentObjectVersions = 
         dependencies.Where(d => d.ObjectVersion1.Id == ov2.Id 
                                 || d.ObjectVersion2.Id == ov2.Id)
                     .Select(d => d.ObjectVersion1)
                     .Union(dependencies.Where(d => d.ObjectVersion1.Id == ov2.Id 
                                                    || d.ObjectVersion2.Id == ov2.Id)
                     .Select(d => d.ObjectVersion2))
                     .Where(o => o.Id != ov2.Id)
                     .GroupBy(o => o.GenericObject.Id)
                     .Select(g => g.OrderByDescending(o => o.Id).FirstOrDefault())
                     .OrderBy(o => o.Id);
foreach (ObjectVersion ov in ov2LatestDependentObjectVersions)
{
    Console.WriteLine(ov.Id);
}
// Output:
// 3
// 4

다음 출력을 얻기 위해 필터링은 어떻게 생겼습니까? 기본적으로 GenericObject가 다른 ov2를 포함하는 최신 ObjectDependencies를 얻고 싶습니다. 필터링은 IQueryable을 사용하여 T-SQL로 직접 변환 할 수 있어야합니다.

var ov2LatestDependencies = dependencies.Where(d => d.ObjectVersion1.Id == ov2.Id 
                                                     || d.ObjectVersion2.Id == ov2.Id)
                                          // ???
                                         .OrderBy(d => d.Name);
foreach (ObjectDependency dependency in ov2LatestDependencies)
{
    Console.WriteLine(dependency.Name);
}
// Output:
// d2
// d3

여기에 바이올린을 만들었습니다 : https://dotnetfiddle.net/OZQlWO

어떤 도움이라도 대단히 감사하겠습니다!

편집하다:

Jason Boyd의 답변을 기반으로 LINQ to 엔터티를 지원하는 다음 솔루션을 사용하게되었습니다. https://dotnetfiddle.net/YSj8ki

var ov2LatestDependencies = dependencies.Where(d => d.ObjectVersion1.Id == ov2.Id 
                                                     || d.ObjectVersion2.Id == ov2.Id)
    .Where(x => x.ObjectVersion1.Id == ov2.Id)
    .Select(x => new
    {
        ObjectDependency = x,
        ObjectVersion = x.ObjectVersion2
    })
    .Union(
        dependencies.Where(d => d.ObjectVersion1.Id == ov2.Id 
                                                     || d.ObjectVersion2.Id == ov2.Id)
        .Where(x => x.ObjectVersion2.Id == ov2.Id)
        .Select(x => new
        {
            ObjectDependency = x,
            ObjectVersion = x.ObjectVersion1
        })
    )
    .GroupBy(x => x.ObjectVersion.GenericObject.Id)
    .Select(x => x.OrderByDescending(y => y.ObjectVersion.Id).FirstOrDefault())
    .Select(x => x.ObjectDependency)
    .OrderBy(d => d.Name);
foreach (ObjectDependency dependency in ov2LatestDependencies)
{
    Console.WriteLine(dependency.Name);
}
// Output:
// d2
// d3
제이슨 보이드

그래서 LINQ 쿼리를 확장 메서드로 리팩토링 할 수있는 자유를 얻었습니다. 그러면 진행 상황을 더 쉽게 따라갈 수 있습니다.

public static class Extensions
{
    public static IQueryable<ObjectDependency> WhereContainsObjectVersion(this IQueryable<ObjectDependency> source, int objectVersionId)
    {
        return
            source
            .Where(x => x.ObjectVersion1.Id == objectVersionId || x.ObjectVersion2.Id == objectVersionId);
    }

    public static IQueryable<ObjectVersion> SelectDependentObjectVersions(this IQueryable<ObjectDependency> source, int objectVersionId)
    {
        return
            source
            .WhereContainsObjectVersion(objectVersionId)
            .Select(x => x.ObjectVersion1.Id == objectVersionId ? x.ObjectVersion2 : x.ObjectVersion1);
    }

    public static IQueryable<TResult> SelectDependentObjectVersions<TResult>(this IQueryable<ObjectDependency> source, int objectVersionId, Func<ObjectDependency, ObjectVersion, TResult> selector)
    {
        return
            source
            .WhereContainsObjectVersion(objectVersionId)
            .Select(x => x.ObjectVersion1.Id == objectVersionId ? selector(x, x.ObjectVersion2) : selector(x, x.ObjectVersion1));
    }

    public static IQueryable<ObjectVersion> SelectByLatestDistinctGenericObject(this IQueryable<ObjectVersion> source)
    {
        return
            source
            .GroupBy(x => x.GenericObject.Id)
            .Select(x => x.OrderByDescending(y => y.Id).FirstOrDefault());
    }

    public static IQueryable<ObjectDependency> SelectByLatestDistinctGenericObject(this IQueryable<ObjectDependency> source, int objectVersionId)
    {
        return
            source
            .SelectDependentObjectVersions(objectVersionId, (x, y) => new { ObjectDependency = x, ObjectVersion = y })
            .GroupBy(x => x.ObjectVersion.GenericObject.Id)
            .Select(x => x.OrderByDescending(y => y.ObjectVersion.Id).FirstOrDefault())
            .Select(x => x.ObjectDependency);
    }
}

그런 다음 다음과 같은 방법으로 호출 할 수 있습니다 (LINQ 쿼리의 일부를 주석 처리하고 확장 메서드가 대체하는 각 쿼리의 부분을 확인할 수 있도록 확장 메서드를 삽입했습니다).

// Get all ObjectDependencies containing ov2
// Output:
// d1
// d2
// d3
Console.WriteLine("Get all ObjectDependencies containing ov2");
IEnumerable<ObjectDependency> ov2Dependencies =
    dependencies
    //.Where(d => d.ObjectVersion1.Id == ov2.Id || d.ObjectVersion2.Id == ov2.Id)
    .WhereContainsObjectVersion(ov2.Id)
    .OrderBy(d => d.Name);
foreach (ObjectDependency dependency in ov2Dependencies)
{
    Console.WriteLine(dependency.Name);
}

// Get all ObjectVersions dependent on ov2
// Output:
// 1
// 3
// 4
Console.WriteLine("Get all ObjectVersions dependent on ov2");
IEnumerable<ObjectVersion> ov2AllDependentObjectVersions =
    dependencies
    //.Where(d => d.ObjectVersion1.Id == ov2.Id || d.ObjectVersion2.Id == ov2.Id)
    //.Select(d => d.ObjectVersion1)
    //.Union(dependencies.Where(d => d.ObjectVersion1.Id == ov2.Id || d.ObjectVersion2.Id == ov2.Id)
    //.Select(d => d.ObjectVersion2))
    //.Where(o => o.Id != ov2.Id)
    .SelectDependentObjectVersions(ov2.Id)
    .OrderBy(o => o.Id);
foreach (ObjectVersion ov in ov2AllDependentObjectVersions)
{
    Console.WriteLine(ov.Id);
}

// Get newest ObjectVersions dependent on ov2 with different GenericObject
// Output:
// 3
// 4
Console.WriteLine("Get newest ObjectVersions dependent on ov2 with different GenericObject");
IEnumerable<ObjectVersion> ov2NewestDependentObjectVersions =
    dependencies
    //.Where(d => d.ObjectVersion1.Id == ov2.Id || d.ObjectVersion2.Id == ov2.Id)
    //.Select(d => d.ObjectVersion1)
    //.Union(dependencies.Where(d => d.ObjectVersion1.Id == ov2.Id || d.ObjectVersion2.Id == ov2.Id)
    //.Select(d => d.ObjectVersion2))
    //.Where(o => o.Id != ov2.Id)
    //.GroupBy(o => o.GenericObject.Id)
    //.Select(g => g.OrderByDescending(o => o.Id).FirstOrDefault())
    .SelectDependentObjectVersions(ov2.Id)
    .SelectByLatestDistinctGenericObject()
    .OrderBy(o => o.Id);
foreach (ObjectVersion ov in ov2NewestDependentObjectVersions)
{
    Console.WriteLine(ov.Id);
}

// Get newest ObjectDependencies containing ov2 with different GenericObject
// Output:
// d2
// d3
Console.WriteLine("Get newest ObjectDependencies containing ov2 with different GenericObject");
IEnumerable<ObjectDependency> ov2NewestDependencies =
    dependencies
    //.Where(d => d.ObjectVersion1.Id == ov2.Id || d.ObjectVersion2.Id == ov2.Id)
    // ???
    .SelectByLatestDistinctGenericObject(ov2.Id)
    .OrderBy(d => d.Name);
foreach (ObjectDependency dependency in ov2NewestDependencies)
{
    Console.WriteLine(dependency.Name);
}

이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.

침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제

에서 수정
0

몇 마디 만하겠습니다

0리뷰
로그인참여 후 검토

관련 기사

분류에서Dev

핵심 데이터 : 관련 엔티티의 속성을 기반으로 엔티티를 가져 오는 방법

분류에서Dev

JPA는 1 개의 공통 엔티티를 기반으로 2 개의 엔티티를 결합합니다.

분류에서Dev

EntityType 필드의 기존 엔티티와 연관되는 새 엔티티 작성

분류에서Dev

linq를 엔티티에 사용하여 관련 엔티티를 기반으로 레코드 가져 오기

분류에서Dev

다른 엔티티의 관계로 엔티티 찾기

분류에서Dev

다른 엔티티의 관계로 엔티티 찾기

분류에서Dev

하위 엔티티의 필드를 기반으로 Hazelcast 맵에서 엔티티를 가져 오는 방법

분류에서Dev

엔터티 간의 관계 만들기

분류에서Dev

관련 엔티티로드

분류에서Dev

다른 엔터티 콘텐츠를 기반으로 엔터티 주문

분류에서Dev

Doctrine2 : 엔티티 클래스를 기반으로 엔티티 생성

분류에서Dev

EF Core 3.0의 모든 테이블에 공통적 인 기본 엔터티

분류에서Dev

기존 엔터티를 참조하는 엔터티 만들기

분류에서Dev

Waterline ORM으로 관련 엔티티 찾기 또는 생성

분류에서Dev

다른 엔터티의 ID로 엔터티 만들기

분류에서Dev

EF Eager는 관련 엔터티에서 관련 엔터티를로드합니다.

분류에서Dev

관련 엔터티 별 Entity Framework 쿼리

분류에서Dev

관련 엔터티가없는 엔터티를 무시하는 관계를 통해 헤더 제목이있는 핵심 데이터 엔터티 목록 양식

분류에서Dev

관계를 통해 has_many의 조인 엔티티에 대한 Rails 필드

분류에서Dev

in Include를 사용하여 관련 데이터 엔티티 ef Core 3.1로드

분류에서Dev

핵심 데이터 관련 엔터티 속성 가져 오기

분류에서Dev

EntityFramework에서 관련 엔터티별로 OrderBy하는 방법

분류에서Dev

Doctrine2에서 관련 엔터티 유지 건너 뛰기

분류에서Dev

@BatchSize 설정시 지연 초기화 예외를 방지하기 위해 관련 엔티티의 데이터 표시

분류에서Dev

교리 Symfony2는 기존 엔티티와 연관 엔티티를 유지합니다.

분류에서Dev

엔티티를 일반 유형으로 전달하고 공통 기능을 추출하려고합니다.

분류에서Dev

SPARQL / DBPedia : 엔티티 페이지 URI를 몰라도 속성을 통해 엔티티 가져 오기

분류에서Dev

부모 엔터티 EFCore 가져 오기에 자식 엔터티로드

분류에서Dev

기본적으로 기본 엔터티에서 자식 개체 값의 합계를 가져 오는 방법

Related 관련 기사

  1. 1

    핵심 데이터 : 관련 엔티티의 속성을 기반으로 엔티티를 가져 오는 방법

  2. 2

    JPA는 1 개의 공통 엔티티를 기반으로 2 개의 엔티티를 결합합니다.

  3. 3

    EntityType 필드의 기존 엔티티와 연관되는 새 엔티티 작성

  4. 4

    linq를 엔티티에 사용하여 관련 엔티티를 기반으로 레코드 가져 오기

  5. 5

    다른 엔티티의 관계로 엔티티 찾기

  6. 6

    다른 엔티티의 관계로 엔티티 찾기

  7. 7

    하위 엔티티의 필드를 기반으로 Hazelcast 맵에서 엔티티를 가져 오는 방법

  8. 8

    엔터티 간의 관계 만들기

  9. 9

    관련 엔티티로드

  10. 10

    다른 엔터티 콘텐츠를 기반으로 엔터티 주문

  11. 11

    Doctrine2 : 엔티티 클래스를 기반으로 엔티티 생성

  12. 12

    EF Core 3.0의 모든 테이블에 공통적 인 기본 엔터티

  13. 13

    기존 엔터티를 참조하는 엔터티 만들기

  14. 14

    Waterline ORM으로 관련 엔티티 찾기 또는 생성

  15. 15

    다른 엔터티의 ID로 엔터티 만들기

  16. 16

    EF Eager는 관련 엔터티에서 관련 엔터티를로드합니다.

  17. 17

    관련 엔터티 별 Entity Framework 쿼리

  18. 18

    관련 엔터티가없는 엔터티를 무시하는 관계를 통해 헤더 제목이있는 핵심 데이터 엔터티 목록 양식

  19. 19

    관계를 통해 has_many의 조인 엔티티에 대한 Rails 필드

  20. 20

    in Include를 사용하여 관련 데이터 엔티티 ef Core 3.1로드

  21. 21

    핵심 데이터 관련 엔터티 속성 가져 오기

  22. 22

    EntityFramework에서 관련 엔터티별로 OrderBy하는 방법

  23. 23

    Doctrine2에서 관련 엔터티 유지 건너 뛰기

  24. 24

    @BatchSize 설정시 지연 초기화 예외를 방지하기 위해 관련 엔티티의 데이터 표시

  25. 25

    교리 Symfony2는 기존 엔티티와 연관 엔티티를 유지합니다.

  26. 26

    엔티티를 일반 유형으로 전달하고 공통 기능을 추출하려고합니다.

  27. 27

    SPARQL / DBPedia : 엔티티 페이지 URI를 몰라도 속성을 통해 엔티티 가져 오기

  28. 28

    부모 엔터티 EFCore 가져 오기에 자식 엔터티로드

  29. 29

    기본적으로 기본 엔터티에서 자식 개체 값의 합계를 가져 오는 방법

뜨겁다태그

보관