URI中指定的查询无效+ Projection + LINQ Select

时间:2016-09-14 20:22:07

标签: linq asp.net-web-api odata projection

如果这是一个重复的问题,我道歉。基本上我想要实现的是让我的投影是一个单独的方法/类,我可以像这样重用它(请记住我是LINQ的初学者)。

public static Expression<Func<MyObject, object>> getProjection()
    {
        return r => new
        {
            Name = r.Name,
            Address = r.Address,
            City = r.City,
            PostalCode = r.PostalCode,
            Province = r.Province,
            Country = r.Country,
            Phone = r.Phone,
            Website = r.Website
        };
    }

但是,当我这样打电话投影时。

var filteredList = db.MyObject.Select(Projections.getProjection()).AsQueryable();
return Ok(filteredList);

然后我收到错误

  

URI中指定的查询无效。找不到房产   在'System.Object'类型上命名为'Name'。

如果我只是通过复制和粘贴将投影辅助方法替换为实际投影,那么它可以正常工作。我只是想通过创建辅助方法“getProjection”来避免为其他Select方法重新编写相同的投影。首先,如果您可以验证这是否是调用Projection的正确方法。其次,如何摆脱OData错误。

由于

2 个答案:

答案 0 :(得分:0)

那么,如果您尝试使用简单方法而不是表达式,该怎么办?

E.g。 :

public static object GetProjection(MyObject o){
    return new{
            Name = o.Name,
            Address = o.Address,
            City = o.City,
            PostalCode = o.PostalCode,
            Province = o.Province,
            Country = o.Country,
            Phone = o.Phone,
            Website = o.Website
    };
}

然后在你的控制器中:

var filteredList = db.MyObject.Select(GetProjection).AsQueryable();
return Ok(filteredList);

答案 1 :(得分:0)

LINQ to Entities需要强大的类型。它们可以是通用的,CAN可以是匿名的。您的问题是您的函数返回弱类型Expression&gt;。

使用强类型来解决此问题,或者不使用投影方法。

答:强类型。这实际上非常整洁,并且可以被视为 lazy 以尝试在此处使用匿名类型。

public class MyRecord { /* fields here */ }
public static Expression<Func<MyObject, MyRecord>> getProjection()
{
    return r => new MyRecord
    {
        Name = r.Name,
        Address = r.Address,
        City = r.City,
        PostalCode = r.PostalCode,
        Province = r.Province,
        Country = r.Country,
        Phone = r.Phone,
        Website = r.Website
    };
}

/* of type IQueryable<MyRecord> */
var filteredList = db.MyObject.Select(getProjection());

B:删除投影方法:<​​/ p>

/* of type IQueryable<Anonymous> - this is why 'var' exists */
var filteredList = db.MyObject.Select(r => new
{
    Name = r.Name,
    Address = r.Address,
    City = r.City,
    PostalCode = r.PostalCode,
    Province = r.Province,
    Country = r.Country,
    Phone = r.Phone,
    Website = r.Website
});

请注意,如果您打算将此方法返回到其他方法,那么您仍然需要强大(非匿名)类型。通过方法传递匿名类型的唯一方法是通过泛型。 e.g:

function T Do<T>(func<T> something) { return something(); }
var anon = Do(() => { a = 1, b = 2 });
C:如果你经常做这个投影并且你不想创建投影课,那么问问自己为什么不呢?&#39;。如果您想避免经常编写此项目代码并且很乐意创建投影类,那么请考虑使用AutoMapper之类的工具。它的使用现在非常普遍。