繁体   English   中英

使用new进行linq查询的更好方法

[英]better way of doing a linq query using new

有没有更好的方法 - 使用Entity Framework从标准SQL服务器中提取:

我正在使用telerik radgrid并提前将字段名称放入列中,因此它将与从linq查询中提取的数据匹配,如:

 var zips = (from z in db.zipcode_lookup select z).ToList();
 zipCodeGrid.DataSource = zips;

它工作正常。 但我需要将两个字段合并为一个,所以我现在需要这样做:

var zips = (from z in db.zipcode_lookup select new 
        {
            zip_code = z.zip_code,
            fullName = z.driver_details.first_name + " " + z.driver_details.last_name,
            driver_id = z.driver_id,
            zone = z.zone
        } ).ToList();

这也很好。 我要做的是不必重新创建已经存在的所有字段(zip_code,driver_id和zone)。

为什么我不能这样做:

 var zips = (from z in db.zipcode_lookup
              select new
              {
                  z,
                  fullName = z.driver_details.first_name + " " + z.driver_details.last_name
              }                           
      ).ToList();

就像我说的那样有效,但我总是遇到这种情况,如果有更好的方法,我真的很感激知道它。

编辑 -

这有点短(就像我说的,在这种情况下没什么大不了的,但有时会有20或30列更大的交易)

var zips = (from z in db.zipcode_lookup
                    select new
                    {
                        z.zip_code,
                        z.zone,
                        z.driver_id,
                        fullName = z.driver_details.first_name + " " + z.driver_details.last_name
                    }                           
            ).ToList();

我编辑了某人的答案,没有意识到必须经过同行评审。 出于某种原因,这适用于下面介绍的新类解决方案:

 var zips = (from z in db.zipcode_lookup.ToList()
                    select new ZipData(z)).ToList();

我不想说有更好的方法。 问题是,在任何一种情况下,C#编译器都将生成一个匿名类型来表示该数据。 你可以解决的唯一方法是改变模型。 即使你写的线数较少(比如只指定你添加一种类型的属性),我认为这并不是一个改进。 会有更多混淆的行为,性能仍然是相同的。 我建议你继续使用你所拥有的东西,除非你不费力地改变你的模型/数据库。

只需将fullName设为ZipCode对象的getter,然后根本不需要执行linq语句。

public string fullName {
   get{
       return driver_details.first_name + " " + driver_details.last_name;
    }
}

更新:这是一个可怕的答案,因为它不适用于EF。 我已经在问题中添加了EF标签以便澄清。 请忽略这个答案,并在你的谎言中投票,因为我自己不能这样做。 [MH]

一种可能的解决方案是声明一个包含您返回的数据的小类:

public class ZipData
{
    public ZipData (zip_code_lookup z) 
    {
        this.zip_code = z.zip_code;
        this.full_name = string.Format("{0} {1}",
                                       z.driver_details.first_name,
                                       z.driver_details.last_name);
       this.driver_id = z.driver_id;
       this.zone = z.zone;
    }

    public string zip_code { get; set; }
    public string full_name { get; set; }
    public int driver_id { get; set; }
    public string zone { get; set; }
}

然后,按如下方式更改Linq表达式:

var zips = (from z in db.zipcode_lookup 
            select new ZipData(z))
           .ToList();

这样,如果你需要全名,你就拥有它。 如果你不这样做,你可以忽略它。 无论哪种方式,构造函数都会为您构建它。 而且您不再使用匿名类型(它不受匿名类型的限制)。

暂无
暂无

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

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