来自 EF SQL 的自定义 IQueryable for Azure Mobile App Service

Custom IQueryable from EF SQL for Azure Mobile App Service

我需要在 Azure 移动应用服务后端 table 控制器中向我的 IQueryable 添加一个 SQL 查询。我需要 ItemLibrary table 来获得默认查询,如图所示。并替换作为默认 table 控制器一部分的 return Query() 或将其与它合并。

这是我需要为 GetAllItemLibraries 做的,但我无法让它工作:

public class ItemLibraryController : TableController<ItemLibrary>
{
    protected override void Initialize(HttpControllerContext controllerContext)
    {
        base.Initialize(controllerContext);

        MIIToolsContext context = new MIIToolsContext();
        DomainManager = new EntityDomainManager<ItemLibrary>(context, Request, enableSoftDelete: true);
    }

    // GET tables/ItemLibrary
    public IQueryable<ItemLibrary> GetAllItemLibraries()
    {
        using (MIIToolsContext context = new MIIToolsContext())
        {
            string sqlQueryString = "SELECT * FROM dbo.ItemSpecification WHERE Id IN (SELECT DISTINCT EquipmentItemID FROM dbo.SiteEquipment WHERE EquipmentSiteID = '8FA79274-C5CC-4610-9D6E-A7062D3CE966')";
            string test = "SELECT TOP 10 * FROM dbo.ItemSpecification";

            return context.ItemLibrary.SqlQuery(sqlQueryString).AsQueryable();
            // return context.ItemLibrary.SqlQuery(test).AsQueryable();
        }

        // possibly merge the SQL IQueryable with the default query?
        // Query.Union([sqlquery])

        // default query
        // return Query();
    }
}

我可以在 Linq 而不是 SQL 中进行查询,但我不知道如何从 ItemLibrary [的上下文中引用 SiteEquipment table table 控制器。我需要将其作为默认查询,但仍将其附加到来自客户端的任何 OData。

对于那些对 Azure 移动应用服务一无所知并想在这里发表评论的人,这里有一个开箱即用的默认 table 控制器包装器示例:

public class ExampleController : TableController<Example>
{
        protected override void Initialize(HttpControllerContext controllerContext)
        {
            base.Initialize(controllerContext);
            MobileServiceContext context = new MobileServiceContext();
            DomainManager = new EntityDomainManager<Example>(context, Request, enableSoftDelete: true);
        }

        // GET tables/Example
        public IQueryable<Example> GetAllExample()
        {
            return Query();
        }

        // GET tables/Example/48D68C86-6EA6-4C25-AA33-223FC9A27959
        public SingleResult<Example> GetExample(string id)
        {
            return Lookup(id);
        }

        // PATCH tables/Example/48D68C86-6EA6-4C25-AA33-223FC9A27959
        public Task<Example> PatchExample(string id, Delta<Example> patch)
        {
            return UpdateAsync(id, patch);
        }

        // POST tables/Example
        public async Task<IHttpActionResult> PostExample(Example item)
        {
            Example current = await InsertAsync(item);
            return CreatedAtRoute("Tables", new { id = current.Id }, current);
        }

        // DELETE tables/Example/48D68C86-6EA6-4C25-AA33-223FC9A27959
        public Task DeleteExample(string id)
        {
            return DeleteAsync(id);
        }
}

不知道这是否是最优雅的方式,但它正在按需工作:

public IQueryable<ItemLibrary> GetAllItemLibrarys(string site)
        {
            using (MIIToolsContext context = new MIIToolsContext())
            {
                //create sql param for site param
                var siteParam = new SqlParameter("@Site", site);

                //use sql to access siteequipment id's by current project site
                var items = context.ItemLibrary.SqlQuery("Select * from dbo.MIIToolsItemLibrary where Id in (SELECT DISTINCT ItemLibraryID FROM dbo.MIIToolsEquipment WHERE ProjectSiteID = @Site)", siteParam).Select(i => i.Id).ToList();

                //use linq on local tablecontroller generated query against sql id results
                return Query().Where(i => items.Any(a => a == i.Id));
            }

            //not using default query
            //return Query();
        }

因为我不知道如何(或最好的方法)访问 SiteEquipment linq 查询对象,所以我只是对该部分使用了 sql,然后能够将结果插入到提供的 ItemLibrary 查询中,所以我仍然可以 运行 odata 查询它。

我还添加了一个“站点”参数,以便移动客户端应用程序仅处理与该项目站点相关的项目。正是我想要的。

我已经测试过了,我认为你的查询字符串因为 EntityData 而不起作用。所以我更改了您的 test 字符串并对其进行了测试。

有效!

public IQueryable<ItemLibrary> GetAllItemLibrarys()
{
        using (ZUMOAPPNAMEContext context = new ZUMOAPPNAMEContext())
        {
            string sqlQueryString = "Select * from dbo.ItemSpecification where Id in (SELECT DISTINCT EquipmentItemID FROM dbo.SiteEquipment WHERE EquipmentSiteID = '8FA79274-C5CC-4610-9D6E-A7062D3CE966')";
            string test = "Select TOP 10 * from dbo.ItemSpecification";
            // Due to EntityData, so sql like below
            test = @"Select TOP 10 *,'111' Id,0x0000000000000FA4 Version,null CreatedAt,null UpdatedAt,CAST(COALESCE(NULL,0) AS BIT) as Deleted from dbo.ItemSpecification";
            var a = context.ItemLibrary.SqlQuery(test).ToList().AsQueryable();
            return a;
        }
}