Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/wcf/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
N层C#应用程序中计算逻辑的放置位置_C#_Wcf_Entity Framework - Fatal编程技术网

N层C#应用程序中计算逻辑的放置位置

N层C#应用程序中计算逻辑的放置位置,c#,wcf,entity-framework,C#,Wcf,Entity Framework,我正在使用以下应用程序结构在C#中开发一个N层应用程序 我的解决方案结构 UI-WPF Prism和ViewModels连接到服务。供商店员工使用 服务-WCF-业务逻辑、数据检索和通过数据层连接到数据库 实体-EF POCO实体-无逻辑 数据-EF DbContext和EDMX-DB连接 Web-ASP.NET MVC应用程序-UI基于Web的版本,功能和客户访问受限。连接到服务 我想知道在哪里有一个实体对象的逻辑,它有计算 下面是示例实体 public class Invoice {

我正在使用以下应用程序结构在C#中开发一个N层应用程序

我的解决方案结构

  • UI-WPF Prism和ViewModels连接到服务。供商店员工使用
  • 服务-WCF-业务逻辑、数据检索和通过数据层连接到数据库
  • 实体-EF POCO实体-无逻辑
  • 数据-EF DbContext和EDMX-DB连接
  • Web-ASP.NET MVC应用程序-UI基于Web的版本,功能和客户访问受限。连接到服务
  • 我想知道在哪里有一个实体对象的逻辑,它有计算

    下面是示例实体

    public class Invoice
    {
        public int InvoiceID { get; set; }
        public DateTime InvoiceDate { get; set; }
        public Decimal SubTotal { get; set; }
        public Decimal? SalesTax { get; set; }
        public Decimal? DiscountPercent { get; set; }
        public Decimal? DiscountAmount { get; set; }
        public decimal Total { get; set; }
    
        public ICollection<InvoiceDetail> InvoiceDetails { get; set; }
    
    }
    
    public class InvoiceDetail
    {
        public int InvoiceDetailID { get; set; }
        public int InvoiceID { get; set; }
        public Decimal Quantity { get; set; }
        public Decimal Price { get; set; }
        public decimal Total { get; set; }
    
        public Invoice Invoice { get; set; }
    
    }
    
    公共类发票
    {
    public int InvoiceID{get;set;}
    公共日期时间发票日期{get;set;}
    公共十进制小计{get;set;}
    公共十进制?销售税{get;set;}
    公共十进制?折扣百分比{get;set;}
    公共十进制?折扣装入{get;set;}
    公共十进制总数{get;set;}
    公共ICollection发票详细信息{get;set;}
    }
    公共类发票明细
    {
    public int InvoiceDetailID{get;set;}
    public int InvoiceID{get;set;}
    公共十进制数量{get;set;}
    公共十进制价格{get;set;}
    公共十进制总数{get;set;}
    公共发票{get;set;}
    }
    
    在上述场景中,当值发生变化时,我应该将计算发票总额的逻辑放在何处。例如,更新SalesTax需要更改发票总额。将行项目添加到发票需要更改小计、税金、折扣和总额

    我想知道我是否可以在服务层这样做,让实体贫血。我所关心的是,我需要不断地在电线上来回发送整个发票对象

    尽管我还没有做一个移动解决方案,但我不确定这在移动环境中是否是一个好主意,因为移动环境可能会因为来回发送发票而消耗数据

    例如,另一个想法是在InvoiceDetail中使用AddLineItem()方法,在Invoice中使用CalculateTotals()

    AddLineItem会自动计算行项目的总计(我可能会将其设置为DB中的计算列),并计算发票的小计、折扣、税金和总计。我假设在这种情况下,如果我想在内部调用CalculateTotals(),例如当SalesTax发生更改时,而不是让客户端调用CalculateChanges,我可能必须删除自动属性。对吗?如果是的话,这就成了我重构EF模板的一个问题,使其不具有自动属性,而是具有支持字段的属性


    请告知哪种方法更好,为什么?或者是一种完全不同的方法。感谢您的帮助。

    我们的工具出现了一个小问题,并将计算放在域对象本身中。一个对象之所以应该知道它的总数,是因为它知道它的子对象。我们的服务层中使用的业务逻辑特定于业务规则,而不是计算。下面是我们的代码示例(注意:我们将C#.Net与MVC3一起使用):

    公共类任务:域库
    {
    公共虚拟ICollection子任务{get;set;}
    [显示(Name=“子任务总成本”)]
    [DisplayFormat(DataFormatString=“{0:0.00}”,ApplyFormatInEditMode=true)]
    //计算属性
    公共虚拟双TotalSubTaskCost
    {
    得到
    {
    if(子任务==null)
    返回0;
    如果(!子任务.Any())
    返回0;
    double it=子任务。其中(a=>a!=null)。
    总数的
    (0,(当前,a)=>当前+a.总成本);
    归还它;
    }
    }
    }
    

    每当查询任务的TotalSubtaskCost时,它都会执行计算。每个子任务都有自己的属性TotalCost。因此,我们为子任务聚合并求和这些值。由于任务总是知道自己的子任务,因此计算应该总是正确的

    我们的工具中存在一个小问题,并将计算放在域对象本身中。一个对象之所以应该知道它的总数,是因为它知道它的子对象。我们的服务层中使用的业务逻辑特定于业务规则,而不是计算。下面是我们的代码示例(注意:我们将C#.Net与MVC3一起使用):

    公共类任务:域库
    {
    公共虚拟ICollection子任务{get;set;}
    [显示(Name=“子任务总成本”)]
    [DisplayFormat(DataFormatString=“{0:0.00}”,ApplyFormatInEditMode=true)]
    //计算属性
    公共虚拟双TotalSubTaskCost
    {
    得到
    {
    if(子任务==null)
    返回0;
    如果(!子任务.Any())
    返回0;
    double it=子任务。其中(a=>a!=null)。
    总数的
    (0,(当前,a)=>当前+a.总成本);
    归还它;
    }
    }
    }
    

    每当查询任务的TotalSubtaskCost时,它都会执行计算。每个子任务都有自己的属性TotalCost。因此,我们为子任务聚合并求和这些值。由于任务总是知道自己的子任务,因此计算应该总是正确的

    “使用WCF、EF、Web和WPF的N层应用程序”这不是很好的定义。您的一个层是表示层,您有几个版本吗?您的其中一个层是使用EF连接到的某种数据库。中间还有哪些层?您的设计说明每一层负责什么?使用存储库:@Deniseskimore:我已经根据您的问题更新了项目结构和它们的责任。@Isak…我下面的回答有用吗?您已经回答了自己的问题,您的设计说明说t
    public class Task : DomainBase
    {
        public virtual ICollection<Subtask> Subtasks { get; set; }
    
        [Display(Name = "Subtask(s) Total Cost")]
        [DisplayFormat(DataFormatString = "{0:0.00}", ApplyFormatInEditMode = true)]
        //calculated property
        public virtual double TotalSubTaskCost
        {
            get
            {
                if (Subtasks == null)
                    return 0;
                if (!Subtasks.Any())
                    return 0;
                double it = Subtasks.Where(a => a != null).
                    Aggregate<Subtask, double>
                        (0, (current, a) => current + a.TotalCost);
                return it;
    
            }
    
        }
    
     }