使用$ select on ef partial class calculated property时出现web api2 odatacontroller错误

时间:2014-01-16 08:30:43

标签: linq entity-framework asp.net-web-api odata

我试图返回一个更大的表的投影,但也返回一个驻留在实体框架类的部分类中的计算属性。

我有以下内容(为简洁起见):

Table: Book

BookID
Title
ImageFileName
ImagePath
Price
AuthorID
CategoryID

这适用于odata控制器:

public class BookController : ODataController
{
    private bookshelfEntities db = new bookshelfEntities();

    public BookController()
    {
        db.Configuration.LazyLoadingEnabled = false;
    }

    // GET odata/Book
    [Queryable]
    public IQueryable<book> GetBook()
    {
        return db.books;
    }
}

对odata控制器的查询返回正确的JSON:

http://localhost:63744/odata/Book?$orderby=Title&$select=BookID%2CTitle%2CImagePath%2CImageFileName

但是我有一个Book的部分类,其中包含ImagePath和ImageFileName的串联,它检查文件是否存在(在服务器上)并返回完整路径或默认书籍封面。

public string BookImagePath
        {
            get
            {
                string physicalPath = GetBookFullPath() + this.BookImage;
                if (System.IO.File.Exists(physicalPath))
                {
                    return BookPath + BookImage;
                }
                else
                {
                    return ConfigurationHelper.GetSetting("RootDir") + "/Defaults/StockBookCovers/bookcover.jpg";
                }
            }
            set
            {
                BookImagePath = value;
            }
        }

当我归还所有书籍时:

http://localhost:63744/odata/Book

BookImagePath在JSON结果中成功返回:

但是当我在$ select:

中包含该属性时
http://localhost:63744/odata/Book?$orderby=Title&$select=BookID%2CTitle%2CImagePath%2CImageFileName%2CBookImagePath

我收到以下错误:

The specified type member 'BookImagePath' is not supported in LINQ to Entities. Only initializers, entity members, and entity navigation properties are supported

我可以猜到为什么它不起作用,它正在尝试为db创建一个SELECT语句,并检查以确保所有请求的字段首先是ef模型的一部分。

有没有办法在没有的情况下在数据库中创建视图,或者创建一个单独的api方法来返回所有数据,然后自己做过滤器?

有趣的是,即使你不在url中使用$ select子句,生成的SQL也会显式引用表中的所有字段(不是SELECT *,而是SELECT,BookID,Title,.etc。 )

我希望它仍然可以进行数据检索,然后将ef对象与任何非db属性一起保存。 (我能理解它,如果它位于 创建的linq表达式的一部分,而不是选择)

例如,如果计算属性引用了未作为select的一部分检索的字段,则计算属性应该/可以处理该字段或抛出不同的错误。

这只是odata实现的一个令人沮丧的“功能”,它在后台使用linq,并且它的linq无法处理作为查询的一部分直接引用的计算属性?

如果是这样,有没有人知道是否有计划改进Linq的实施以允许这个?

感谢您的任何帮助/想法。

对于版本参考,这是我的packages.config中的Microsoft软件包:

<package id="Microsoft.AspNet.Mvc" version="5.0.0" targetFramework="net45" />
  <package id="Microsoft.AspNet.Mvc.FixedDisplayModes" version="5.0.0" targetFramework="net45" />
  <package id="Microsoft.AspNet.Razor" version="3.0.0" targetFramework="net45" />
  <package id="Microsoft.AspNet.Web.Optimization" version="1.1.2" targetFramework="net45" />
  <package id="Microsoft.AspNet.WebApi" version="5.0.0" targetFramework="net45" />
  <package id="Microsoft.AspNet.WebApi.Client" version="5.0.0" targetFramework="net45" />
  <package id="Microsoft.AspNet.WebApi.Core" version="5.0.0" targetFramework="net45" />
  <package id="Microsoft.AspNet.WebApi.OData" version="5.0.0" targetFramework="net45" />
  <package id="Microsoft.AspNet.WebApi.WebHost" version="5.0.0" targetFramework="net45" />
  <package id="Microsoft.AspNet.WebPages" version="3.0.0" targetFramework="net45" />
  <package id="Microsoft.AspNet.WebPages.Data" version="3.0.0" targetFramework="net45" />
  <package id="Microsoft.AspNet.WebPages.WebData" version="3.0.0" targetFramework="net45" />
  <package id="Microsoft.Bcl" version="1.1.6" targetFramework="net45" />
  <package id="Microsoft.Bcl.Build" version="1.0.13" targetFramework="net45" />
  <package id="Microsoft.Data.Edm" version="5.6.0" targetFramework="net45" />
  <package id="Microsoft.Data.OData" version="5.6.0" targetFramework="net45" />
  <package id="Microsoft.Web.Infrastructure" version="1.0.0.0" targetFramework="net45" />

0 个答案:

没有答案