实体框架核心中的动态选择

发布于 2025-01-25 04:50:01 字数 2590 浏览 2 评论 0原文

我正在创建一个执行动态选择字段的过程。 例如:

List<Company> items = await entity
    .Skip(model.Start)
    .Take(model.Length)
    .Select(GenerateDynamicSelect<Company>("Id,Name"))
    .ToListAsync();

公司实体是:

public class Category
{
    public int Id { get; set; }
    public string? Name { get; set; }
    ...others 100 properties...
}

public class Company 
{
    public int Id { get; set; }
    public int? CategoryId { get; set; }
    public Category? Category { get; set; }
    public string? Code { get; set; }
    public string? Name { get; set; }
    ...others 100 properties...
}

如果我使用的话,一切正常,

GenerateDynamicSelect<Company>("Id,Name")

但是如何使用嵌套字段?

GenerateDynamicSelect<Company>("Id,Name,Category.Name")

避免加载类别表的所有列很重要。

我写的代码:

private static Expression<Func<T, T>> GenerateDynamicSelect<T>(string fields)
{
    Type type = typeof(T);
    ParameterExpression parameter = Expression.Parameter(type, "x");
    NewExpression objToInitialise = Expression.New(type);
    HashSet<string> parsedColumns = new();

    BindingFlags searchFlags = BindingFlags.IgnoreCase | BindingFlags.Public | BindingFlags.Instance;
    IEnumerable<MemberAssignment> bindings = fields.Split(',')
        .Select(columnName => columnName.Trim().ToLower())
        .Where(columnName => !parsedColumns.Contains(columnName))
        .Select(columnName =>
            {
                parsedColumns.Add(columnName);
                PropertyInfo? property;
                if (columnName.Contains('.'))
                {
                    string[] parts = columnName.Split('.');
                    property = type.GetProperty(parts[0], searchFlags);

                    how i can do?
                }
                else
                {
                    property = type.GetProperty(columnName, searchFlags);
                }
                MemberExpression originalValue = Expression.Property(parameter, property);
                return Expression.Bind(property, originalValue);
            }
        );
    MemberInitExpression initializedMember = Expression.MemberInit(objToInitialise, bindings);
    return Expression.Lambda<Func<T, T>>(initializedMember, parameter);
}

谢谢。我使用.NET 6

I am creating a procedure that performs a dynamic select of the fields.
For example:

List<Company> items = await entity
    .Skip(model.Start)
    .Take(model.Length)
    .Select(GenerateDynamicSelect<Company>("Id,Name"))
    .ToListAsync();

Company Entity is:

public class Category
{
    public int Id { get; set; }
    public string? Name { get; set; }
    ...others 100 properties...
}

public class Company 
{
    public int Id { get; set; }
    public int? CategoryId { get; set; }
    public Category? Category { get; set; }
    public string? Code { get; set; }
    public string? Name { get; set; }
    ...others 100 properties...
}

everything works fine if I use

GenerateDynamicSelect<Company>("Id,Name")

But how do I use nested fields?

GenerateDynamicSelect<Company>("Id,Name,Category.Name")

It is important to avoid loading all the columns of the Category table.

The code i wrote:

private static Expression<Func<T, T>> GenerateDynamicSelect<T>(string fields)
{
    Type type = typeof(T);
    ParameterExpression parameter = Expression.Parameter(type, "x");
    NewExpression objToInitialise = Expression.New(type);
    HashSet<string> parsedColumns = new();

    BindingFlags searchFlags = BindingFlags.IgnoreCase | BindingFlags.Public | BindingFlags.Instance;
    IEnumerable<MemberAssignment> bindings = fields.Split(',')
        .Select(columnName => columnName.Trim().ToLower())
        .Where(columnName => !parsedColumns.Contains(columnName))
        .Select(columnName =>
            {
                parsedColumns.Add(columnName);
                PropertyInfo? property;
                if (columnName.Contains('.'))
                {
                    string[] parts = columnName.Split('.');
                    property = type.GetProperty(parts[0], searchFlags);

                    how i can do?
                }
                else
                {
                    property = type.GetProperty(columnName, searchFlags);
                }
                MemberExpression originalValue = Expression.Property(parameter, property);
                return Expression.Bind(property, originalValue);
            }
        );
    MemberInitExpression initializedMember = Expression.MemberInit(objToInitialise, bindings);
    return Expression.Lambda<Func<T, T>>(initializedMember, parameter);
}

Thanks. I use .NET 6

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文