代码之家  ›  专栏  ›  技术社区  ›  user2006633

ServiceStack AutoQuery-使用泛型和自定义属性简化

  •  0
  • user2006633  · 技术社区  · 10 年前

    这个问题来自另一个 Simplify OrmLite with AutoQuery.

    ServiceStack AutoQuery允许我所有不同的Get(AKindOfType dto)共享相同的代码,如下所示:(我有很多模型,比如Company,我还有两个问题试图进一步简化代码)

    // ====== Model.cs ========
    [Route("/company/search")]
    public class QueryableCompany : QueryBase<Company>
    {
        public int? Id { get; set; }
        public string Company { get; set; }
        public int? CompanyNo { get; set; }
        public bool? Active { get; set; }
    }
    public class Company
    {
        [AutoIncrement]
        public int id { get; set; }
        public string company { get; set; }
        public int companyNo { get; set; }
        public bool active { get; set; }
    }
    // ====== Service.cs ========
    public IAutoQuery AutoQuery { get; set; }
    
    public object Get(QueryableCompanies dto)
    {
        var q = AutoQuery.CreateQuery(dto, Request.GetRequestParams());
        var r = AutoQuery.Execute(dto, q);
        return r.Results; 
    }
    
    // ====== Global.asax.cs ========
    public override void Configure(Container container)
    {
        //...
        Plugins.Add(new AutoQueryFeature { MaxLimit = 100 });
        //...
    }
    

    然后,根据上面的代码,我还有两个问题。

    1) 由于我有很多请求dto,它们在Get(QueryableXXXdto)中的代码都是相同的;如何使用一个通用的Get()方法返回所有不同类型的DTO,例如:

    public object Get<T>(T dto) where T : IQuery
    {
        var q = AutoQuery.CreateQuery(dto, Request.GetRequestParams());
        return AutoQuery.Execute(dto, q).Results;
    }
    

    2) 在上面的Company示例中,QueryableCompany类似乎与Company类非常相似,AutoQuery是否可以为Company类的成员提供一些属性,并避免创建另一个类似的QueryableCompany?

    1 回复  |  直到 7 年前
        1
  •  3
  •   Community Vlad V    7 年前

    a) 让您的服务共享一个公共基类

    不能让服务调用泛型方法签名作为入口点。但是您的服务可以继承一个公共服务基类,您的实现可以调用该基类,例如:

    public class CompanyServices : MyServiceBase
    {
        public object Get(QueryCompany request)
        {
            return base.MyQuery(request);
        }
    }
    

    b) 重写AutoQuery Services的默认类

    如果希望所有AutoQuery服务保持不变,则对实现进行泛型化的另一个选项是提供自己的 Custom AutoQueryServiceBase class 所有AutoQuery Services都可以使用,例如:

    public abstract class MyAutoQueryServiceBase : AutoQueryServiceBase
    {
        public override object Exec<From>(IQuery<From> dto)
        {
            var q = AutoQuery.CreateQuery(dto, Request.GetRequestParams());
            return AutoQuery.Execute(dto, q).Results;
        }
    
        public override object Exec<From, Into>(IQuery<From, Into> dto)
        {
            var q = AutoQuery.CreateQuery(dto, Request.GetRequestParams());
            return AutoQuery.Execute(dto, q).Results;
        }
    }
    

    然后,您可以告诉AutoQuery将您的基类用于具有以下功能的所有AutoQuery服务:

    Plugins.Add(new AutoQueryFeature { 
        AutoQueryServiceBaseType = typeof(MyAutoQueryServiceBase)
    });
    

    c) 动态生成服务入口点

    如果您需要更多的灵活性,可以采用AutoQuery用于 generate your Services implementations and register them dynamically /


    2) 在上面的Company示例中,QueryableCompany类似乎与Company类非常相似,AutoQuery是否可以为Company类的成员提供一些属性,并避免创建另一个类似的QueryableCompany?

    不能对请求查询DTO和正在查询的POCO数据模型使用相同的POCO,因为引用类定义中定义的类是一个构建错误,例如:

    public class Company : IQuery<Company> {}
    

    你可以使用继承来保存财产,尽管我个人 recommend against doing so for Request DTO 秒:

    public class QueryCompany : Company, IQuery<Company> {}
    

    由于C#不支持多重继承,您的公司类要么需要显式定义IQuery财产,要么继承 QueryBase 类,例如:

    public class Company : QueryBase { ... }