代码之家  ›  专栏  ›  技术社区  ›  Guilherme Caixeta

返回对象内部筛选的列表

  •  0
  • Guilherme Caixeta  · 技术社区  · 8 年前

    编辑

    完整的场景是,我需要检索对象列表(在本例中为Person),并对属性文件上返回的集合应用过滤器,简而言之,我只想获取具有多个特定类型文件的人员,但我也只想从此查询中检索此特定文件。

    对象表示:

    public class Person(){
      public string name {get; set;}
      public int id {get; set;}
      public List<File> file {get; set;}
    }
    

    和文件实体:

    public class File(){
      public string name {get; set;}
      public int id {get; set;}
      public int extension {get; set;}
      public int type_file {get; set;}
    }
    

    OBS公司 :我使用EF6和。net框架。

    示例:

    //returning a IQueryable
    var t = service.getAll<person>()
       .Where(x => x.id == id)
       .Where(y => y.files.Any(l => l.type_file == 1))
       .FirstOrDefault();
    
    3 回复  |  直到 4 年前
        1
  •  1
  •   Abion47    8 年前

    因为你没有提供 Minimal, Complete and Verifiable Example ,我为您的场景创建了一个简单的表示:

    static List<Person> GetAllPersons()
    {
        var ret = new List<Person>(new [] 
                                { 
                                    new Person(){ Id = 10 }, 
                                    new Person(){ Id = 4 },
                                    new Person(){ Id = 8 }
                                });
    
        var rnd = new Random();
    
        foreach(var person in ret)
            for(int i = 0; i <3; i++)
                person.Files.Add(new File() { FileType = rnd.Next(1,3) , Name= "File " + (i + 1).ToString() });
    
        return ret;
    }
    
    class Person
    {
        public int Id { get; set; }
        public List<File> Files { get;set; }
    
        public Person()
        {
            Files = new List<File>();
        }
    }
    
    class File
    {
        public int FileType { get; set; }
        public string Name { get; set; }
    }
    

    如果我很了解你的需要,你想改变 Files 第一个的属性 Person 符合您的限制。

    应该是这样的:

    public static void Main()
    {   
        var Id = 4;
        var all = GetAllPersons();
    
        var t = all
           .Where(x => x.Id == Id)
           .Select(P => new Person()
                    { 
                        Id = P.Id, 
                        Files = P.Files.Where(l => l.FileType == 1).ToList()
                    })
           .Where(y => y.Files.Count > 0)
           .FirstOrDefault();
    }
    

    This complete example is available on dotnetfiddle

    但可以肯定的是,这种逻辑毫无意义,而且在所有可能的方面都是错误的。我很有信心,你面临的问题是从你混乱的逻辑中提出来的,而且它正在变得更糟。

    我建议你在经历这种危险的方式之前,先整理好你的逻辑。

        2
  •  0
  •   Abion47    8 年前

    您正在使用 FirstOrDefault ,它将返回可枚举对象(或 null ,如果列表为空*)。如果需要列表,请删除此方法调用并添加 ToList 相反

    var t = service.getAll<person>()
                   .Where(x => x.id == id)
                   .Where(y => y.files.Any(l => l.type_file == 1))
                   .ToList();
    

    *更精确的答案是,它将返回 IEnumerable 表示。对于值类型,这将是该类型的默认值(例如,0表示 int ,对于,为false bool 等)。对于引用类型,这将是 无效的

        3
  •  0
  •   Guilherme Caixeta    8 年前

    这是我解决这个问题的办法,谢谢你的帮助。

            //var person is DTO
            var person= base.Get(id);
            var list = new List<FileDTO>();
            person.file.ForEach(delegate (FileDTO obj)
            {
                if (obj.type_file== (int)TypeFile.Attachment)
                {
                    obj.archive = null;
                    list.Add(obj);
                }
            });
            person.file = list;
            return person;