从子总和记录更新父级

时间:2017-11-02 20:50:59

标签: c# asp.net asp.net-mvc entity-framework

我在visual studio 2012中创建了解决方案,这个解决方案是在4个项目中进行的:

  1. 项目表示层(asp.net mvc)

  2. 业务实体层

    public class Parent
    {
      public int Id {get; set;}
      public decimal TotalPrice {get; set;}
      //the rest of properties
      public private ICollection<Child> Children {get; set;}
    }
    
    public class Child
    {
      public int Id {get; set;}
      public decimal UnitePrice {get; set;}
      //the rest of properties
      public int ParentId {get; set;}
      public private Parent Parent {get; set;}
    }
    
  3. 数据访问层(ado.net数据模型实体框架+存储库)

    //class repository for child
    public class ParentRepository :IDisposable, IParentRepository
    {
    //implemente GetAll
       public IEnumerable<Parent>GetAllParents()
       {
          return context.parents;
       }
       public Parent GetParentById(int ParentId)
       {
          return context.Parents.Find(parentId);
       }
    
       //implemente GetAll CRUD for Parent
       public void AddParent(Parent parent)
       {
          context.Parents.Add(parent);
       }
    
       public void UpdateParent(Parent parent)
       {
          context.Parents.Attach(parent);
           context.Entry(Parents).State = EntityState.Modified;
    
       }
    
       public void DeleteParent(int parentId)
       {
          Parent parent = context.Parents.Find(parentId);
          context.Parents.Remove(parent);
       }
       // save methode
       public int Save()
       {
          return context.SaveChanges();
       }
    } 
    
    //class repository for child
    public class ChildRepository : IDisposable,IChildRepository
    {
    
    EFContext context = new EFContext();
    
    //Get the children for one parent
    
    public IEnumerable<Child> GetAllChildrenByParentId(int parentId)
    {
       var query = context.Children.Where(c=>c.ParentId == parentId)
    }
    
      //the rest of code to implemente CRUD of children
    
      public Child GetChildById(int childId)
      {
         return context.Children.Find(childId);
      }
    
      //implemente CRUD for Child
      public void AddChild(Child child)
      {
         context.Children.Add(child);
      }
    
      public void UpdateChild(Child child)
      {
        context.Children.Attach(child);
        context.Entry(child).State = EntityState.Modified;
    
      }
    
      public void DeleteChild(int childId)
      {
         Child child = context.Children.Find(childId);
         context.Children.Remove(child);
      }
      // save methode
      public int Save()
      {
         return context.SaveChanges();
      }
    }
    
  4. 但是对于Bll类中的业务逻辑层,我尝试通过子项的单位价格总和来计算父项的总数

    public class ParentChildBll
    {
      //retreive the parent by its parentid
       public Parent GetParent(int parentId){
          using (var repository = new ParentRepository())
          {       
            return repository.GetParentById(parentId);
          }  
       }
       public decimal GetTotal(int parentId)
       {
          int total;
          //call the GetParent() methode for getting parent to update its totalprice
          Parent parent = GetParent(parentId);
          //call the methode GetAllChildrenByParentId of ChildRepository that return 
         //ienumerebal<Child> and then call the extention methode Sum for calculate 
        // the sum of unite prices of child
    
         using (var repository = new ChildRepository())
         {       
            var query = reopsitory.GetAllChildrenByParentId(parentId).Sum(d=>d.UnitePrice);
           total=query;
         }
    
         parent.TotalPrice =total;
         UpdateParent(parent);//call update parent
         return total;
     }
     //implement crud parent
     public void UpdateParent(Parent parent)
     {
       //call repository update methode in BLL class
       using (var repository = new ParentRepository())
       {       
           reopsitory.UpdateParent(parent);
           repository.Save();
       }
       //
      }
    }
    
  5. 我尝试过:

    - 每次插入/更新/删除子项时我都必须调用getTotal()方法来更新ParentChildBLL类中的父级totalprice,

    public void AddChild(Child child)
    {
       //call repository update methode in BLL class
       using (var repository = new ChildRepository())
       {       
           reopsitory.AddChild(child);
           repository.Save();
       }
       //update totalPrice of parent each insertion of child
       getTotal(child.ParentId);
    }
    

    当插入/更新/删除子项时,每个子unitprice的总和是否有更好的实现更新父总数

    -i不知道必须在存储库或Bll中实现calculte总和在哪里?

    如果你帮助我,我将不胜感激。

    很快就好了

3 个答案:

答案 0 :(得分:0)

一般情况下,我们避免存储计算出的属性,但如果符合以下条件则可能有用:

  • 涉及子实体,
  • 子实体的更新频率低于检索父实体的次数。
  

当插入/更新/删除子项时,每个子unitprice的总和是否有更好的实现更新父总数

考虑更新差异:

public class ParentChildBll
{
    public decimal UpdateTotal(int parentId, decimal oldUnitPrice, decimal newUnitPrice)
    {
        var parent = GetParent(parentId);
        parent.TotalPrice += newUnitPrice - oldUnitPrice;
        UpdateParent(parent);
    }

    public void AddChild(Child child)
    {
        var oldUnitPrice = 0m;
        var newUnitPrice = child.UnitePrice;

        using (var repository = new ChildRepository())
        {
            repository.AddChild(child);
            repository.Save();
        }

        UpdateTotal(child.ParentId, oldUnitPrice, newUnitPrice);
    }
}

答案 1 :(得分:0)

首先在EF代码中,您可以使用computed column来存储TotalPrice。它应该是read-only字段。

public class Parent
{
    public int Id { get; set; }

    [DatabaseGenerated(DatabaseGeneratedOption.Computed)]
    public decimal TotalPrice
    {
        get
        {
            return Children == null ? 0 : Children.Sum(x => x.UnitePrice);
        }
    }

    //the rest of properties
    public virtual ICollection<Child> Children { get; set; }
}

答案 2 :(得分:0)

您只需在linq代码中使用sum函数即可从数据库获取父母

例如在业务层中为您编写代码

 public IEnumerable<Parent>GetAllParents()
 {
      return context.parents.Select(p=> new Parent 
      {
       Id = p.Id,
       TotalPrice = p.Children.Sum(x=>x.UnitePrice)
      });
} 

我认为不需要UpdateTotal方法