1 回答
TA贡献1872条经验 获得超3个赞
您的方法期望返回一个 IEnumerable,但您只返回传入的单个 Product DTO。
签名应该是:
public async Task<ProductDTO> AddProducts(ProductDTO ProductDTO, List<ParameterDTO> ParameterDTO)
鉴于 ProductDTO 具有 ParameterDTO 的集合,是否还需要第二个参数?(看起来它会发送两次参数)
根据您的实体定义,我发现了一些问题:
[ForeignKey("ProductTypeId")]
public int ProductTypeId { get; set; }
public virtual ProductType ProductType { get; set; }
应该
[ForeignKey("ProductType")] // FK to the reference property.
public int ProductTypeId { get; set; }
public virtual ProductType ProductType { get; set; }
所有导航属性(例如集合和产品类型)都应声明为虚拟的,否则您将获得不一致的行为。如果需要,声明为虚拟的将可以访问延迟加载,其他将保留为#null。
Product 和 Parameter 都不应该引用 ProductType,据我所知,它可能应该只引用 Product 以避免非规范化问题。(具有不同 ProductTypes 集的参数的产品。)
在处理导航属性时,我建议从实体中删除 FK 属性并使用映射 (EF6)/阴影属性。(英孚核心)
例如:
public class ProductParameter
{
public int Id { get; set; }
public virtual Product Product { get; set; } // No ProductId/ParameterId
public virtual Parameter Parameter { get; set; }
public string Value { get; set; }
}
modelBuilder.Entity<Product>()
.HasMany(x => x.ProductParameters)
.WithOne(x => x.Product)
.HasForeignKey("ProductId"); // Sets up a shadow property.
映射 FK 的问题在于有 2 个真实来源供参考。ProductParameter.ProductId 与 ProductParameter.Product.Id。通常这些将指向相同的值,但代码可能依赖于一条路径而不是另一条路径,如果只更改一条路径而不更改另一条路径,则会导致一致性错误。
谨慎使用异步操作。如果您通过 ID 或任何其他相对快速的操作拉回单个记录,请不要使用异步,因为注册延续会产生性能成本。(更快地进行同步调用)异步适用于预计需要一段时间的操作。(即超过一秒)
最后,该代码可能有效,但它没有很好地利用 EF,单独设置所有这些实体,并且您通常不希望多次调用 SaveChanges 以确保数据一起提交或根本不提交(如果有)问题。
var EntryProduct = _context.Products.Find(ProductDTO.ProductId);
if (EntryProduct != null)
return ProductDTO;
var product = new Product
{
Id = ProductDTO.ProductId,
Number = ProductDTO.Number,
Amount = ProductDTO.Amount,
PrimeCostEUR = ProductDTO.PrimeCostEUR,
};
var parameterIds = ParameterDTO.Select(x => x.Id).ToList();
var parametersToAdd = context.Parameters
.Where(x => parameterIds.Contains(x.ParameterId))
.Select(x => new ProductParameter
{
Product = product,
Parameter = x
}).ToList();
product.ProductParameters.AddRange(parametersToAdd);
await _context.SaveChangesAsync();
return ProductDTO;
我不建议为 DbContext (_context) 使用模块级变量,因为上下文应该是短暂的,以帮助避免一个工作流打算保存而其他代码可能不会保存的潜在问题。如果它由 IoC 容器注入并限定为与请求匹配的生命周期,那么这应该不会导致任何问题。请注意上下文打开的时间超过需要的时间。
- 1 回答
- 0 关注
- 115 浏览
添加回答
举报