[英]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.