URI 中指定的查询无效 + 投影 + LINQ Select
The query specified in the URI is not valid + Projection + LINQ Select
如果这是一个重复的问题,我深表歉意。基本上我想要实现的是让我的投影是一个单独的 method/class,我可以像这样重用它(请记住我是 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
};
}
但是,当我这样调用Projection时。
var filteredList = db.MyObject.Select(Projections.getProjection()).AsQueryable();
return Ok(filteredList);
然后我得到错误
The query specified in the URI is not valid. Could not find a property
named 'Name' on type 'System.Object'.
如果我仅通过复制和粘贴将 Projection 辅助方法替换为实际的 Projection,那么它就可以工作。我只是想通过创建辅助方法 "getProjection" 来避免为其他 Select 方法再次重写相同的投影。首先,如果您可以验证这是否是调用 Projection 的正确方法。其次,我怎样才能摆脱那个 OData 错误。
谢谢
那么,如果您尝试使用简单的方法而不是表达式呢?
例如:
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);
LINQ to Entities 需要强类型。它们可以是通用的,并且可以是匿名的。你的问题是你的函数 return 是一个弱类型 Expression>。
使用强类型解决,或者不使用投影方式。
A:强型。这实际上非常整洁,可以被认为是 懒惰 尝试在这里使用匿名类型。
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:去除投影方式:
/* 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
});
请注意,如果您打算将此 return 用于另一种方法,您仍然需要强(非匿名)类型。通过方法传递匿名类型的唯一方法是通过泛型。例如:
function T Do<T>(func<T> something) { return something(); }
var anon = Do(() => { a = 1, b = 2 });
C:如果您经常进行此投影并且您不想创建投影 类 那么问问自己 'why not?'。如果您想避免经常编写此项目代码并且乐于创建投影 类,那么请考虑使用诸如 AutoMapper 之类的工具。现在使用很普遍。
如果这是一个重复的问题,我深表歉意。基本上我想要实现的是让我的投影是一个单独的 method/class,我可以像这样重用它(请记住我是 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
};
}
但是,当我这样调用Projection时。
var filteredList = db.MyObject.Select(Projections.getProjection()).AsQueryable();
return Ok(filteredList);
然后我得到错误
The query specified in the URI is not valid. Could not find a property named 'Name' on type 'System.Object'.
如果我仅通过复制和粘贴将 Projection 辅助方法替换为实际的 Projection,那么它就可以工作。我只是想通过创建辅助方法 "getProjection" 来避免为其他 Select 方法再次重写相同的投影。首先,如果您可以验证这是否是调用 Projection 的正确方法。其次,我怎样才能摆脱那个 OData 错误。
谢谢
那么,如果您尝试使用简单的方法而不是表达式呢?
例如:
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);
LINQ to Entities 需要强类型。它们可以是通用的,并且可以是匿名的。你的问题是你的函数 return 是一个弱类型 Expression>。
使用强类型解决,或者不使用投影方式。
A:强型。这实际上非常整洁,可以被认为是 懒惰 尝试在这里使用匿名类型。
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:去除投影方式:
/* 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
});
请注意,如果您打算将此 return 用于另一种方法,您仍然需要强(非匿名)类型。通过方法传递匿名类型的唯一方法是通过泛型。例如:
function T Do<T>(func<T> something) { return something(); }
var anon = Do(() => { a = 1, b = 2 });
C:如果您经常进行此投影并且您不想创建投影 类 那么问问自己 'why not?'。如果您想避免经常编写此项目代码并且乐于创建投影 类,那么请考虑使用诸如 AutoMapper 之类的工具。现在使用很普遍。