【问题标题】:how to return selected columns based on user choice如何根据用户选择返回选定的列
【发布时间】:2017-11-28 18:22:48
【问题描述】:

我正在尝试根据一个名为 fields 的参数来限制 API 返回的字段,我接受多个字符串来执行此操作

私有只读字符串[] 字段;

public string[] SelectiveSerializer(string fields)
{
    string[] _fields;
    var fieldColl = fields.Split(',');
    _fields = fieldColl
        .Select(f => f.ToLower().Trim())
        .ToArray();
    return _fields;

}

我希望能够根据用户在 _fields 中给我的任何内容来选择我返回的内容。正常的做法:

 var linq = (from entity in db.users
             where entity.ID== id
              && entity.ON== false
             select( new {
             ID = entity.ID,
             FirstName = entity.FirstName,
             LastName =entity.LastName,
             FotherName = entity.FotherName
             }).ToList();

但在这里我必须指定 Select (ID, FirstName ..etc) 中的字段,我希望它根据字段 [] 具有的动态。有没有办法做到这一点?

这样的(这是错误的):

var linq = (from entity in db.users
             where entity.ID== id
              && entity.ON== false
             select( new {
             foreach (string s in _fields)
             {
                    entity.s;
             }
             }).ToList();

【问题讨论】:

  • 可能类似于this?

标签: asp.net-mvc entity-framework asp.net-web-api lambda


【解决方案1】:

对每个赋值使用三元表达式

var user = entityContext.Users.Where(u => u.ID == id)
    .Select(u => new {
        ID =  _fields.Contains['id'] ? u.ID : 0,
        FirstName = _fields.Contains['firstname'] ? u.FirstName : null,
        LastName = _fields.Contains['lastname'] ? u.LastName : null,
        otherName = _fields.Contains['othername'] ? u.otherName : null
    })
    .ToList();

我还将字段名称放在HashSet<string> 中以获得更好的性能。

var _fields = new HashSet<string>(fields.Split(',').Select(f => f.ToLower().Trim()));

此解决方案保留所有属性,但将不需要的属性设置为 null。如果您想动态添加属性,请参阅另一个 SO 问题:How to dynamically create a class in C#?。但请注意,这仅在动态处理此类对象的情况下才有用。

【讨论】:

  • 这不是会返回所有字段,但如果不选择则返回 null 吗?
  • 是的。除非使用一些重度反射的东西,否则你不能拥有带有可变字段的类型。即使它是匿名类型。请参阅 SO 问题How to dynamically create a class in C#?
【解决方案2】:

我终于能够用最少的工作做到这一点。 假设过滤器是一个字符串列表。字符串数组。

所以为了避免反射和所有爵士乐,我遍历每条记录并查看变量是否在过滤器列表中,然后使用 (var,val) 创建一个 dic 条目,假设同一记录中没有重复的 var,这如果你愿意,可以抓住,但我没有这个问题。 然后在最后将该 dic 添加到列表中。 该方法接受匿名类型列表和过滤器列表。

public static List<Dictionary<string, object>> filteredList(IEnumerable source, string[] filter)
    {
        var filteredList = new List<Dictionary<string, object>>();
        foreach (var single in source)
        {
            var type = single.GetType();
            var props = type.GetProperties();
            var singleRecord = new Dictionary<string, object>();
            foreach (var v in props)
            {
                if (filter.Contains(v.Name))
                {
                    var tempValue = type.GetProperty(v.Name).GetValue(single, null);
                    singleRecord.Add(v.Name, tempValue);
                }

            }
            filteredList.Add(singleRecord);
        }
        return filteredList;
    }

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-05-10
    • 1970-01-01
    • 1970-01-01
    • 2022-11-23
    相关资源
    最近更新 更多