亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

如何在EF Core中實現添加相關數據的方法?

如何在EF Core中實現添加相關數據的方法?

C#
慕桂英546537 2022-11-21 16:02:08
如何實現添加相關數據的方法EF core?需要將哪些對象提交給 add 方法,它應該返回什么?我需要在數據庫中添加相關數據,例如: {        "productId": 0,        "number": "xxx",        "amount": 5.65,        "primeCost": 20.33,        "productTypeId": 0,        "parameters": [            {                "id": 0,                "name": "Type",                "value": null            },            {                "id": 3,                "name": "steel grade",                "value": "CK45"            },            {                "id": 4,                "name": "diameter",                "value": "40"            }        ]    }這些是我的模型類:public class Product //: BaseObject{    public int Id { get; set; }    public string Name { get; set; }    public string Number { get; set; }    public double Amount { get; set; }    public double PrimeCost { get; set; }    [ForeignKey("ProductTypeId")]    public int  ProductTypeId {  get; set; }    public virtual ProductType ProductType { get; set; }    public ICollection<ProductParameter> ProductParameters { get; set; } = new List<ProductParameter>();}public class ProductType //: BaseObject{       public int Id { get; set; }    public string NameType { get; set; }    public ICollection<Parameter> Parameters { get; set; } = new List<Parameter>();    public ICollection<Product> Products { get; set; } = new List<Product>();} public class Parameter //: BaseObject{    public int Id { get; set; }    public string Name { get; set; }    [ForeignKey("ProductTypeId")]    public int ProductTypeId { get; set; }    public ProductType ProductType { get; set; }    public ICollection<ProductParameter> ProductParameters { get; set; } = new List<ProductParameter>();} public class ProductParameter //: BaseObject{    public int Id { get; set; }    public int ProductId { get; set; }    public virtual Product Product { get; set; }    public int ParameterId { get; set; }    public virtual Parameter Parameter { get; set; }    public string Value { get; set; }}
查看完整描述

1 回答

?
守著一只汪

TA貢獻1872條經驗 獲得超4個贊

您的方法期望返回一個 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 容器注入并限定為與請求匹配的生命周期,那么這應該不會導致任何問題。請注意上下文打開的時間超過需要的時間。


查看完整回答
反對 回復 2022-11-21
  • 1 回答
  • 0 關注
  • 147 瀏覽

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號