繁体   English   中英

ASP.NET 内核 Web API:异步任务有问题?

[英]ASP.NET Core Web API: having trouble with async task?

我正在研究 ASP.NET 核心 Web API 项目,我希望控制器异步返回结果。 但是我在通过 id 调用时遇到问题。

楷模:

public class Product
{
    [Key]
    public int Id { get; set; }

    [Required]
    public string ProductType { get; set; }

    [Required]
    [MaxLength(250)]
    public string ProductDescription { get; set; }

    [Required]
    public int ProductCategory { get; set; }

    //Navigation Properties
    public int TravelPackageId { get; set; }
    public TravelPackage TravelPackage { get; set; }
}

public class TravelPackage
{
    [Key]
    public int Id { get; set; }

    [Required]
    [MaxLength(50)]
    public string PackageName { get; set; }

    //Navigation Properties
    public List<Product> Products { get; set; }
}

TravelPackage有一个产品列表。 当我通过 id 调用travelPackage时,我也需要返回该产品列表。

这是我的两个调用的存储库(所有travelPackages和特定的travelPackage by id)

public class TravelPackageRepository : ITravelPackageRepository
{
    private readonly DataContext _context;

    public TravelPackageRepository(DataContext context)
    {
        _context = context;
    }

    public async Task<TravelPackage> GetProductByIdAsync(int id)
    {
        return await _context.TravelPackages.Include(t => t.Products.Select(p => new
        {
            Id = t.Id,
            PackageName = t.PackageName,
            Products = t.Products.Select(product => new Product()
            {
                Id = product.Id,
                ProductType = product.ProductType,
                ProductDescription = product.ProductDescription,
                ProductCategory = product.ProductCategory,
                TravelPackageId = product.TravelPackageId
            })
        })).FirstAsync(t => t.Id == id);
     
    }

    public async Task<System.Collections.Generic.IReadOnlyList<TravelPackage>> GetTravelPackagesAsync()
    {
        return await _context.TravelPackages
            .Include(x => x.Products)
            .ThenInclude(x => x.TravelPackage)
            .ToListAsync();
    }
}

但我收到以下错误:

System.InvalidOperationException:表达式 't.Products.AsQueryable().Select(p => new <>f__AnonymousType2`3(Id = t.Id, PackageName = t.PackageName, Products = t.Products.AsQueryable().Select (product => new Product() { Id = product.Id, ProductType = product.ProductType, ProductDescription = product.ProductDescription, ProductCategory = product.ProductCategory, TravelPackageId = product.TravelPackageId})))' 在“包含”内无效操作,因为它不代表属性访问:'t => t.MyProperty'。 要定位在派生类型上声明的导航,请使用强制转换 ('t => ((Derived)t).MyProperty') 或 'as' 运算符 ('t => (t as Derived).MyProperty')。 集合导航访问可以通过组合 Where、OrderBy(Descending)、ThenBy(Descending)、Skip 或 Take 操作进行过滤。

在实现存储库和 async/await 之前,这是我的用于 travelPackages 的 controller,它运行良好:

[HttpGet("{id}")]
public  ActionResult<TravelPackage> GetTravelPackage(int id)
{
        var item = _context.TravelPackages.Where(package => package.Id == id).Select(package => new
        {
            Id= package.Id,
            PackageName =package.PackageName,
            Products = package.Products.Select(product => new Product()
            {
                Id = product.Id,
                ProductType = product.ProductType,
                ProductDescription = product.ProductDescription,
                ProductCategory = product.ProductCategory,
                TravelPackageId = product.TravelPackageId
            })
        });

        return Ok(item);
}

我没有太多使用 .net 内核、异步/等待任务和 linq 的经验,所以我不知道如何处理这个错误。

谢谢

该错误是由以下原因引起的:

_context.TravelPackages.Include(t => t.Products.Select

Include 语句应表示属性访问,但您选择的是 Include 中的匿名 object。

在本例中,导航属性为 Products,因此将其更改为:

_context.TravelPackages.Include(t => t.Products).Select

在 Products 导航属性之后有一个右括号。 因此,您将包括 Product 并且 select 查询如下。

JMP 注意到存在语法错误。 但是你也试图返回一个匿名的 object。 所以试试这个:

 return await _context.TravelPackages
    .Where(package => package.Id == id)
    .Select(t => 
     new TravelPackage
        {
            Id = t.Id,
            PackageName = t.PackageName,
            Products = t.Products.Select(product => new Product()
            {
                Id = product.Id,
                ProductType = product.ProductType,
                ProductDescription = product.ProductDescription,
                ProductCategory = product.ProductCategory,
                TravelPackageId = product.TravelPackageId
            })
        }).FirstOrDefaultAsync();

但由于您包含所有属性,您可以缩短它:

return await _context.TravelPackages
    .Include(t => t.Products)
    .Where(package => package.Id == id)
    .FirstOrDefaultAsync();

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM