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

时间:2014-08-30 06:48:33

标签: generics attributes servicestack ormlite-servicestack

此问题来自Simplify OrmLite with AutoQuery.

的另一个问题

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

// ====== 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(QueryableXXX dto)中的代码都是一样的;如何使用单个通用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)在上面的公司示例中,类QueryableCompany看起来与类Company类似,AutoQuery是否可以为类Company的成员提供一些属性,并避免创建另一个类似的QueryableCompany?

1 个答案:

答案 0 :(得分:3)

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

您无法将服务调用泛型方法签名作为入​​口点。但是您的服务可以继承您的实现可以调用的公共服务基类,例如:

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

b)覆盖AutoQuery Services的默认类

如果您希望所有AutoQuery Services保持不变,那么对您的实现进行通用化的另一个选择是提供您自己的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)在上面的公司示例中,类QueryableCompany看起来与类Company类似,AutoQuery是否可以为类Company的成员提供一些属性,并避免创建另一个类似的QueryableCompany?

您不能对请求查询DTO和您要查询的POCO DataModel使用相同的POCO,因为它构建错误是为了引用您在类定义中定义的类,例如:

public class Company : IQuery<Company> {}

虽然我个人recommend against doing so for Request DTO s:

,但您可以使用继承来保存属性
public class QueryCompany : Company, IQuery<Company> {}

由于C#不支持多重继承,因此公司类需要显式定义IQuery属性或继承QueryBase类,例如:

public class Company : QueryBase { ... }