gpt4 book ai didi

c# - 如何将针对 DTO 的 OData 查询映射到另一个实体?

转载 作者:可可西里 更新时间:2023-11-01 08:19:39 26 4
gpt4 key购买 nike

我的问题与这个非常相似:How do I map an OData query against a DTO to an EF entity?我有一个简单的设置来测试 ASP.NET Web API OData V4 $filter 功能。我想做的是“别名” ProductDTO 的一些属性以匹配 Product 实体的属性。例如,用户将使用以下请求调用 ProductsController:

GET products?$filter=DisplayName eq ‘test’

产品类:

public class Product
{
public int Id { get; set; }
public string Name { get; set; }
public int Level { get; set; }
public Product()
{ }
}

ProductDTO 类:

public class ProductDTO
{
public int Id { get; set; }
public string DisplayName { get; set; }
public int DisplayLevel { get; set; }
public ProductDTO(Product product)
{
this.DisplayName = product.Name;
this.DisplayLevel = product.Level;
}
}

产品 Controller :

public class ProductsController : ApiController
{
public IEnumerable<ProductDTO> Get(ODataQueryOptions<Product> q)
{
IQueryable<Product> products = this._products.AsQueryable();
if (q.Filter != null) products = q.Filter.ApplyTo(this._products.AsQueryable(), new ODataQuerySettings()) as IQueryable<Product>;
return products.Select(p => new ProductDTO(p));
}
}

当然我得到以下异常:

Could not find a property named 'DisplayName' on type 'TestAPI.Models.Product'

我尝试通过将以下行添加到 WebApiConfig.cs 来使用新引入的别名功能

public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{

IEdmModel model = GetModel();
config.MapODataServiceRoute("*", "*", model);
}

private static IEdmModel GetModel()
{
ODataModelBuilder builder = new ODataConventionModelBuilder();
EntitySetConfiguration<Product> products = builder.EntitySet<Product>("Product");
products.EntityType.Property(p => p.Name).Name = "DisplayName";
products.EntityType.Property(p => p.Level).Name = "DisplayLevel";
return builder.GetEdmModel();
}
}

我想我没有正确使用别名功能,因为抛出了与上述相同的异常。如果我调用以下请求,它会起作用,但这不是我想要实现的:

GET products?$filter=Name eq ‘test’

更新:

我同意 gdoron 的观点,Get 端点应如下所示:

public IEnumerable<ProductDTO> Get(ODataQueryOptions<ProductDTO> q)

但这应该可以在没有 AutoMapper 的情况下解决吗?

最佳答案

我找到了一个不使用 AutoMapper 的解决方案。

ProductsController 现在看起来像这样:

public class ProductsController : ApiController
{
public IEnumerable<ProductDTO> Get(ODataQueryOptions<ProductDTO> q)
{
IQueryable<Product> products = this._products.AsQueryable();

IEdmModel model = GetModel();
IEdmType type = model.FindDeclaredType("TestAPI.Models.Product");
IEdmNavigationSource source = model.FindDeclaredEntitySet("Products");
ODataQueryOptionParser parser = new ODataQueryOptionParser(model, type, source, new Dictionary<string, string> { { "$filter", q.Filter.RawValue } });
ODataQueryContext context = new ODataQueryContext(model, typeof(Product), q.Context.Path);
FilterQueryOption filter = new FilterQueryOption(q.Filter.RawValue, context, parser);

if (filter != null) products = filter.ApplyTo(products, new ODataQuerySettings()) as IQueryable<Product>;
return products.Select(p => new ProductDTO(p));
}
}

WebApiConfig:

public static class WebApiConfig
{
public static void Register(HttpConfiguration config)
{

IEdmModel model = GetModel();
config.MapODataServiceRoute("*", "*", model);
}

private static IEdmModel GetModel()
{
ODataModelBuilder builder = new ODataConventionModelBuilder();
EntitySetConfiguration<Product> product = builder.EntitySet<Product>("Products");
product.EntityType.Name = "Product";
product.EntityType.Namespace = "TestAPI.Models";
product.EntityType.Property(p => p.Name).Name = "DisplayName";
product.EntityType.Property(p => p.Level).Name = "DisplayLevel";
return builder.GetEdmModel();
}
}

关于c# - 如何将针对 DTO 的 OData 查询映射到另一个实体?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26628521/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com