简体   繁体   English

使用IQueryable将具有导航属性的实体转换为DTO

[英]Convert Entity with navigation property to DTO using IQueryable

Suppose I have following entities and dtos 假设我有以下实体和dto

public class Country
{
    public List<NameLocalized> NamesLocalized;
    public CountryData Data;
}

public class NameLocalized
{
    public string Locale;
    public string Value;
}

public class CountryData
{
    public int Population;
}

public class CountryDto
{
    public String Name;
    public CountryDataDto Data;
}

public class CountryDataDto
{
    public int Population;
}

I need to convert Country to CountryDto (and ideally, I want to make a single query to the database). 我需要将Country转换为CountryDto(理想情况下,我想对数据库进行单个查询)。 I have received few suggestions in my other questions on Stackoverflow, and can now accomplish the task, but only partially. 在有关Stackoverflow的其他问题中,我收到的建议很少,现在可以完成任务,但只能完成一部分。 I am stuck at how to convert navigation property ( CountryData in this case). 我被困在如何转换导航属性(在这种情况下为CountryData )。 I was suggested to use LINQKit for this, but have no idea how to implement it. 建议我为此使用LINQKit ,但不知道如何实现它。 Here is my code which populates only Name property but not Data navigation property. 这是我的代码,仅填充Name属性,而不填充Data Navigation属性。

public static async Task<List<CountryDto>> ToDtosAsync(this IQueryable<Country> source, string locale)
{
    if(source == null)
    {
        return null;
    }

    var result = await source
        .Select(src => new CountryDto
        {    
           Name = src.NamesLocalized.FirstOrDefault(n => n.Locale == locale).Name
        })
        .ToListAsync();

    return result; 
}

This answer gave me the hint for my solution. 这个答案给了我解决方案的提示。 You need to use LINQKit and build Expression to convert the navigation property. 您需要使用LINQKit并构建Expression来转换导航属性。

public static Expression<Func<CountryData, CountryDataDto>> ConverterExpression = cd => new CountryDataDto
        {
            Population = cd.Population
        };

public static async Task<List<CountryDto>> ToDtosAsync(this IQueryable<Country> source, string locale)
{
    if(source == null)
    {
        return null;
    }

    var result = await source
        .AsExpandable
        .Select(src => new CountryDto
        {    
           Name = src.NamesLocalized.FirstOrDefault(n => n.Locale == locale).Name
           Data = ConverterExpression.Invoke(src.Data)
        })
        .ToListAsync();

    return result; 
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM