Loading [MathJax]/jax/output/CommonHTML/config.js
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >如何开始创建Linq- to -Repository to HttpRequest框架

如何开始创建Linq- to -Repository to HttpRequest框架
EN

Stack Overflow用户
提问于 2014-11-13 17:12:42
回答 1查看 363关注 0票数 1

举个例子,我有一个简单的WebAPi2,它有一个名为ParentsController的单一控制器,它是一个标准的WebAPi2 ApiController。这是样板。

在客户端,我创建了一个Repository基类,并在此基础上创建了一个ParentRepository类。

ApiRequester:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
    public class ApiRequester
{
    readonly Uri _apiServiceBaseAddress;
    readonly String _apiControllerPath;
    readonly Guid _apiKey;

    public ApiRequester(string apiServiceBaseAddress, string apiControllerPath, Guid apiKey)
    {
        _apiServiceBaseAddress = new Uri(apiServiceBaseAddress);
        _apiControllerPath = apiControllerPath;
        _apiKey = apiKey;
    }
    public async Task<T> Get<T>(string queryParameters)
    {
        using (var client = new HttpClient { BaseAddress = _apiServiceBaseAddress })
        {
            //client.Timeout = TimeSpan.FromSeconds(60);
            client.DefaultRequestHeaders.Add("X-APIKey", _apiKey.ToString());

            var response = await client.GetAsync(_apiControllerPath + queryParameters);

            var result = await response.Content.ReadAsAsync<T>();

            return result;
        }
    }

    public async Task<T> Post<T>(string queryParameters, T entity)
    {
        using (var client = new HttpClient { BaseAddress = _apiServiceBaseAddress })
        {
            client.DefaultRequestHeaders.Add("X-APIKey", _apiKey.ToString());
            HttpResponseMessage response = null;

            response = await client.PostAsJsonAsync<T>(_apiControllerPath + queryParameters, entity);

            response.EnsureSuccessStatusCode();
            var result = await response.Content.ReadAsAsync<T>();
            return result;
        }
    }

    public async Task<T> Put<T>(string queryParameters, T entity)
    {
        using (var client = new HttpClient { BaseAddress = _apiServiceBaseAddress })
        {
            client.DefaultRequestHeaders.Add("X-APIKey", _apiKey.ToString());
            var response = await client.PutAsJsonAsync<T>(_apiControllerPath + queryParameters, entity);
            response.EnsureSuccessStatusCode();

            var result = await response.Content.ReadAsAsync<T>();

            return result;
        }
    }

    public async Task Delete(string queryParameters)
    {
        using (var client = new HttpClient { BaseAddress = _apiServiceBaseAddress })
        {
            client.DefaultRequestHeaders.Add("X-APIKey", _apiKey.ToString());

            var response = await client.DeleteAsync(_apiControllerPath + queryParameters);
            response.EnsureSuccessStatusCode();
        }
    }
}

RepositoryBase:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public abstract class RepositoryBase<T> where T : class, IEntity
{
    readonly ApiRequester _requester;

    protected RepositoryBase(string apiBaseUri, string controllerPath, Guid apiKey)
    {
        if (String.IsNullOrWhiteSpace(apiBaseUri))
            throw new ArgumentNullException("apiBaseUri");

        if (apiKey.Equals(default(Guid)))
            throw new ArgumentNullException("apiKey");

        _requester = new ApiRequester(apiBaseUri, controllerPath, apiKey);
    }
    public virtual Task<ICollection<T>> GetAsync(string queryParameters)
    {
        return _requester.Get<ICollection<T>>(queryParameters);
    }

    public virtual Task<T> PostAsync(string queryParameters, T entity)
    {
        return _requester.Post<T>(queryParameters, entity);
    }

    public virtual Task<T> PutAsync(string queryParameters, T entity)
    {
        return _requester.Put<T>(queryParameters, entity);
    }
    public virtual Task DeleteAsync(string queryParameters)
    {
        return _requester.Delete(queryParameters);
    }
}

ParentRepository:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
    public class ParentRepository : RepositoryBase<Parent>
{
    public ChannelRepository(string apiBaseUri, string controllerPath, Guid apiKey)
        : base(apiBaseUri, controllerPath, apiKey)
    { }
}

因此,客户端的消费者可以进行调用,从API获取父级列表,如下所示:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
pRepo = new ParentRepository();
var parents = await pRepo.GetAsync();

// Do something with parent collection.

父实体如下所示:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public class Parent : IEntity
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public Guid ParentId { get; set; }

    public String Name { get; set; }

// Navigation Properties
    public virtual ICollection<Child> Children { get; set; }
}

我希望在我的存储库方法上允许类似于以下内容:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
pRepo = new ParentRepository();
var parents = await pRepo.GetAsync().Where(p => p.Name == "aName").Include(p => p.Children);

这就是我被卡住的地方。

我如何在我的GetAsync()方法中拦截它,以便构建我的http请求?

要获取“Where”子句,我需要创建一个扩展方法吗?类似于:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public static ICollection<TEntity> Where(this ICollection<TEntity> source, Func<TEntity> , bool> predicate)
{
// Do something or not?
}

但是然后呢?

对于'Include‘部分,我在这里需要什么,也许是从System.Reflection获取子集合属性名的东西?

同样,我如何拦截GetAsync()方法中的推断?

我知道可能有更简单的方法可以用重载方法做我想要的事情,但我喜欢创建一个类似linq的方法的想法。

编辑:

为了清楚我想要什么,我认为我需要使用表达式树(还不确定如何)来将我的linq表达式转换为web uri:

因此,在我的客户端中,我写道:var parents = await pRepo.GetAsync().Where(p => p.Name == "aName").Include(p => p.Children);

然后该表达式被转换为如下形式:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
GET /api/parents/?name=aName&IncludeChildren=true

然后,客户端可以执行Get请求。注意,这应该是我可以在我构建的任何客户端中使用的东西,目标是任何类型的基于web的应用程序接口,不一定需要是WebAPI。

EN

回答 1

Stack Overflow用户

发布于 2014-11-14 03:39:53

根据我(有限的)经验,Web API控制器有一些可选参数,用于过滤和排序,然后将这些参数转换为对数据访问层中的Repository类的类似linq的请求。其中没有一个驻留在客户端上,客户端正在使用查询字符串中的标准HTTP约定向Web API控制器发出请求,例如:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
GET /api/parent?minimumId=5&maximumId=20&orderBy=Name

可选的查询字符串参数可以转换为Linq或Dynamic Linq,以查询底层DAL提供的某种IQueryable。

您可能不会经常在对Web API控制器的请求中看到类似linq的行为,因为控制器本质上是面向HTTP的,而倾向于类似HTTP的行为。

如果你真的想用类似Linq的语法包装对Web API控制器的调用,我会考虑使用Dynamic Linq将你的数据(Funcs/Expression/String/等)转换成Linq查询,因为它至少让你自己避免了对反射的大惊小怪。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/26914529

复制
相关文章
java httprequest选项_HTTPRequest类
com.google.appengine.api.urlfetch.HTTPRequest
全栈程序员站长
2022/09/07
4160
HTTPRequest类
HTTPRequest 封装通过 URLFetchService 进行的单个 HTTP 请求。
哲洛不闹
2018/09/19
1.3K0
github import repository创建github仓库
现在,假设我们从零开发,那么最好的方式是先创建远程库,然后,从远程库克隆。 首先,登陆GitHub,创建一个新的仓库,名字叫blog 1.先创建一个项目仓库 2. 我们勾选Initialize this repository with a README,这样GitHub会自动为我们创建一个README.md文件。创建完毕后,可以看到README.md文件 Github线上的仓库项目建好了,我们就可以在自己的服务器上安装git服务端了,安装完之后,我们需要从线上将项目仓库中的文件clone克隆一份到我们自己服
吴裕超
2018/02/28
1.3K0
HTTPRequest类
HTTPRequest 封装通过 URLFetchService 进行的单个 HTTP 请求。
哲洛不闹
2018/09/14
1.1K0
Django的HttpRequest[通俗易懂]
HttpReqeust对象 服务器接收到http协议的请求后,会根据报文创建HttpRequest对象,这个对象不需要我们创建,直接使用服务器构造好的对象就可以。视图的第一个参数必须是HttpRequest对象,在django.http模块中定义了HttpRequest对象的API。
全栈程序员站长
2022/09/14
3390
HttpServletRequest、HttpRequest区别
#HttpRequest RestTemplate,我们知道RestTemplate是spring提供的一个http请求工具,表明都是用来进行http请求用的。
知识浅谈
2021/05/17
1.2K0
从 Spring 开始,谈谈如何自学 Java 常用框架
我记得,我刚找工作时简历上写的是精通 java,工作后写的是熟悉 java,现在写的是了解 java。 你学的越多,就会知道自己不懂的越多,那时的我们找工作,学过就叫精通,用过就写熟悉,听过就写了解
阿凯
2018/06/29
1.3K0
向github中已创建好的repository提交文件
此时可这样解决: git config core.filemode false git config core.eol lf
西西嘛呦
2020/08/26
1K0
Maven Repository
The usefully link for Maven Reponsitory display as below:
Hongten
2018/09/13
10.7K0
Maven Repository
32.HttpRequest对象的学习
我们知道WSGIRequest是一个HTTP请求对象,里面包括了提交的方式和URL路径。
全栈程序员站长
2022/09/07
2710
32.HttpRequest对象的学习
Django之HttpRequest和HttpResponse
Django 是围绕着 Request 与 Response 进行处理,也就是无外乎“求”与“应”。
菲宇
2019/06/13
1.4K0
Django之HttpRequest和HttpResponse
Django之HttpRequest和HttpReponse
  当一个web请求链接进来时,django会创建一个HttpRequest对象来封装和保存所有请求相关的信息,并且会根据请求路由载入匹配的试图函数,每个请求的试图函数都会返回一个HttpResponse对象。
全栈程序员站长
2022/07/18
3410
Spring Repository解析---以Mongo Repository为例
Spring 为java web 开发领域提供了大量的优秀的框架,第三方包,大大解放了生产力,本文主要介绍Spring Repository在连接数据库这边做的一些封装,并以Mongo Repository为例,详细阐述下Repository实现机制,本文基于spring-data-mongo1.10.4
方丈的寺院
2019/08/05
1.1K0
Spring Repository解析---以Mongo Repository为例
如何发布Jar包到Maven Central Repository
Maven Central 网站并不提供注册的功能,你需要到 Sonatype 网站上进行注册。而事实上,Sonatype 网站也没有直接提供一个注册链接。真正的注册入口在 issues tracker 上。一旦完成注册后,你需要创建包含待发布包信息的 issue。
lambeta
2018/08/17
2.8K0
如何发布Jar包到Maven Central Repository
【愚公系列】2022年01月 Python教学课程 46-Django框架之HttpRequest
与python字典不同,QueryDict类型的对象用来处理同一个键带有多个值的情况
愚公搬代码
2022/12/01
1K0
【愚公系列】2022年01月 Python教学课程 46-Django框架之HttpRequest
如何使用Sonatype Nexus Repository 3 :Maven仓库配置
Sonatype Nexus Repository 3(Sonatype Nexus 3)是一个由Sonatype开发的仓库管理工具,用于管理和托管各种软件构件(如Maven构件、Docker镜像等)。它提供了一种集中化的方式来存储、管理和分发软件构件,以帮助团队协作和构建自动化。
coderidea
2023/09/09
5K0
如何使用Sonatype Nexus Repository 3 :Maven仓库配置
Django源码学习-19-HttpRequest
Django网络应用开发的5项基础核心技术包括模型(Model)的设计,URL 的设计与配置,View(视图)的编写,Template(模板)的设计和Form(表单)的使用。
小团子
2019/08/20
4350
Django源码学习-19-HttpRequest
点击加载更多

相似问题

实体框架作为UnitOfWork/Repository?

10

Repository +实体框架的UnitOfWork模式

40

Ansible:如何检查Artifactory Repository是否存在,是否存在,更新Repository配置,如果没有创建Repository

113

创建HttpRequest和转发HttpRequest有什么区别?

13

创建HttpServer HttpRequest会话

10
添加站长 进交流群

领取专属 10元无门槛券

AI混元助手 在线答疑

扫码加入开发者社群
关注 腾讯云开发者公众号

洞察 腾讯核心技术

剖析业界实践案例

扫码关注腾讯云开发者公众号
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文