LINQ。加入多个表时出现匿名类型错误

时间:2013-01-22 21:21:41

标签: asp.net linq entity-framework-5

我试图根据我的模型返回IQueryable。

但我需要两次加入同一个查找表。然后将查询变量返回到gridview。

public IQueryable<Benchmark> GetBenchMarks([QueryString("hydrant")] string hydrant,
[QueryString("revdate")] string revdate, [QueryString("street")] string street,
[QueryString("quadrant")] string quadrant, [QueryString("desc")] string desc) {

    IQueryable<Benchmark> query = from p in _db.Benchmarks
    join s in _db.Streets on p.Street1Number equals s.Id
    join s2 in _db.Streets on p.Street2Number equals s2.Id
    select new {
        Street1Name = s.StreetName,
        p.OrderNumber,
        p.HydrantNumber,
        Street2Name = s2.StreetName,
        p.RevisionDate,
        p.Quadrant,
        p.Description,
        p.Street1Number
    };
}

所以在第二次连接到s2时有一条红色的波浪线。以下错误。

  

Error 5 Cannot implicitly convert type 'System.Linq.IQueryable<AnonymousType#1>' to 'System.Linq.IQueryable<Benchmarks.Model.Benchmark>'. An explicit conversion exists (are you missing a cast?) C:\Projects\Benchmarks\Benchmarks\Benchmarks_Home.aspx.cs 63 25 Benchmarks

2 个答案:

答案 0 :(得分:2)

由于您使用select new {...}结束查询,因此您将为每个结果创建一个匿名对象。相反,请使用select p,每个结果都是Benchmark

然而,看起来回归Benchmark并不是你想要的。在这种情况下,您可能希望将查询更改为IQueryableIQueryable<dynamic>类型(并且可能也会更改GetBenchMarks函数的返回类型,除非它确实返回{{1 }}!)。

第二种(可能更好的)替代方法是创建一个表示此匿名类型的类,并使用它。

答案 1 :(得分:0)

您的查询结果是IEnumerable个匿名对象,因此无法转换为Benchmark

如果您想设置一些其他属性(Street1Name - 显然未在数据库上映射),您可以执行以下操作:

 IQueryable<Benchmark> query = from p in _db.Benchmarks
            join s in _db.Streets on p.Street1Number equals s.Id
            join s2 in _db.Streets on p.Street2Number equals s2.Id
        select new { 
                 ....
        };
 var ex = query.ToList();
 var result = new List<Benchmark>();
 foreach(bn in ex){
      result.Add(new Benchmark{ OrderNumber = bn.OrderNumber .... });
 }
// return result.AsQueryable();   
// but now it losts the point to return it as queryable, because the query was already executed so I would simply reurn that list
 return result;

另一种选择是从查询中创建表示对象的新类,并从以下方法返回它:

... select new LoadedBenchmark { Street1Name = s.StreetName ....}