【问题标题】:How do I best handle data in my application如何最好地处理我的应用程序中的数据
【发布时间】:2016-10-14 08:06:22
【问题描述】:

正在开发用于工资单的 C# 应用程序。作为警告,我对这一切都很陌生,只是被投入其中并享受它,但在短时间内吸收了很多东西。我目前正在学习 LINQ 和课程。我正在从我们的帐户 SQL 服务器中获取发票行,并根据销售额和可以从数据中确定的某些情况向人员付款。请参阅下面的示例:

Ord_Inv_No      Delivery_Date       Trmnl_Key   TrmnlGrp_Key
INV-00059754    2016-05-02 07:00:00 23          3
INV-00059839    2016-05-02 16:01:00 56          3

这是数据的一小部分,但它提供了我想要分析的要点。我有一个类如下所示:

class SalesItem
{

    public string DriverName { get; set; }
    public DriverData DriverData { get; set; }
    public int TerminalKey { get; set; }
    public int TerminalGroupKey { get; set; }
    public string DeliveryDate { get; set; }
    public string CustomerLocation { get; set; }
    public int? CustomerLocationKey { get; set; }
    public bool? IsCredited { get; set; }
    public string InvoiceNumber { get; set; }
    public string TermianlGroupDesc { get; set; }

    public SalesItem(string driverName, int terminalKey, int terminalGroupKey, string deliveryDate, 
        string customerLocation, int? customerLocationKey, bool? isCredited, string invoiceNumber, string terminalGroupDesc)
    {
        this.DriverName = driverName;
        this.TerminalKey = terminalKey;
        this.TerminalGroupKey = terminalGroupKey;
        this.DeliveryDate = deliveryDate;
        this.CustomerLocation = customerLocation;
        this.CustomerLocationKey = customerLocationKey;
        this.IsCredited = isCredited;
        this.InvoiceNumber = invoiceNumber;
        this.TermianlGroupDesc = terminalGroupDesc;
    }

我正在尝试实现一种方法,我可以 1. 将每个 SalesItem(每一行)存储为一个集合,因为没有更好的词。我想遍历SalesItem 的集合并找出一些事情,例如当发票行出现两次时,不同的Trmnl_Key 和两个不同的Ord_Inv_No 彼此具有完全相同的日期并返回两人的薪酬最高。我为此编写了一些逻辑,它正在处理我正在通过 SQLConnection/Command/Reader/Etc 获取的DataTable,但是在处理一周的数据时,所有这些都非常缓慢和繁琐,而且我无法进行比较可靠地工作。更进一步,这些行将在 WPF 中的 DataGrid 中标记,以便在会计软件出现异常情况时人工验证他们的工资。

现在,我正在尝试保存集合,如下所示(这只是当前的迭代,我有几天的尝试失败了。)

 private void GetInformation(object sender, SelectionChangedEventArgs e)
    {
        ComboBox currentItem = sender as ComboBox;
        int driverKey = Convert.ToInt32(currentItem.SelectedValue);
        DriverData driver = new DriverData();
        driver.SetDriverData(driverKey);
        int years = driver.ServiceYears;
        List<SalesItem> items =  (from o in transportationDb._Payroll_Orders
                                 where o.Ord_Driver_Key == driverKey &&
                                 o.Delivery_Date >= new DateTime(2016, 5, 2) && o.Delivery_Date <= new DateTime(2016, 5, 8)
                                 select new SalesItem(
                                     o.Driver_Name,
                                     o.Trmnl_Key,
                                     o.TrmnlGrp_Key,
                                     o.Delivery_Date.ToString(),
                                     o.CustLoc_Description,
                                     o.Ord_CustLoc_Key,
                                     o.Credits, o.Ord_Inv_No, o.TrmnlGrp_Description )).ToList();


        dataGrid.ItemsSource = items;

    }

任何智慧或方向将不胜感激

【问题讨论】:

  • 你在使用实体框架吗?
  • 您需要在类级别的 GetInformation 方法范围之外声明 List&lt;SalesItem&gt; items 在分配 ItemsSource 后您是否看到 dataGrid 中的项目也许您应该谷歌如何绑定列表 到 DataGridView.. 并查看使用它的 DataSource 属性
  • EF 性能不佳。使用 TSQL 和 DataReader。
  • @Paparazzi 如果你想要性能,你不会只使用存储过程吗?
  • @BlueEyedBehemoth 如果你想为每个案例写一个 sp。即使我确实有一些 sp,我仍然会使用 TSQL 和 DataReader。

标签: c# wpf linq ienumerable


【解决方案1】:

当然,这与您所拥有的并没有太大不同,但请尝试一下,看看它是否适合您:

private void GetInformation(object sender, SelectionChangedEventArgs e)
{
    ComboBox currentItem = sender as ComboBox;
    int driverKey = Convert.ToInt32(currentItem.SelectedValue);
    DriverData driver = new DriverData();  //What's this for?
    driver.SetDriverData(driverKey); //What's this for?
    int years = driver.ServiceYears; //What's this for?
    var startDate=new DateTime(2016, 5, 2);
    var endDate=new DateTime(2016, 5, 8);
    var items = transportationDb._Payroll_Orders
      .Where(o=>o.Ord_Driver_Key == driverKey)
      .Where(o=>o.Delivery_Date >= startDate && o.Delivery_Date <= endDate)
      .Select(o=>new SalesItem {
        DriverName=o.Driver_Name,
        ...
      });
    dataGrid.ItemsSource = items;
}

如果您的 Orders 表在 Ord_Driver_key 和 Delivery_Date 上有一个索引,那么这个查询应该很快。

【讨论】:

    【解决方案2】:

    我希望这在某种程度上有所帮助。我不太确定您要达到的目标。保存功能可能如下所示,但我不知道您使用的是哪种连接。请注意,我正在检查以确保记录不存在。

     private void Save(SalesItem item)
        {
            if(!transportationDb._Payroll_Orders.Any(p => p.Ord_Inv_No == item.InvoiceNumber))
            {
                transportationDb._Payroll_Orders.Add(item.PayrollOrder);
                transportationDb.SaveChanges();
            }
            else
            {
                // Already exists
            }
        }
    

    将您的课程更新为您想要的任何方式,但由于对您的对象应该是什么样子的有限了解,我会这样做。

    class SalesItem
    {
    
        public SalesItem(_Payroll_Orders po == null, DriverData dd == null)
        {
            this._Payroll_Order = po != null ? po : new _Payroll_Orders();
            this.DriverData = dd != null ? dd : new DriverData();
        }
    
        private _Payroll_Orders _Payroll_Order { get; set; }
    
        public _Payroll_Orders PayrollOrder
        {
            get { return _Payroll_Order; }
            set { _Payroll_Order = value; }
        }
    
        public string DriverName 
        {
            get { return _Payroll_Order.Driver_Name; }
            set { _Payroll_Order.Driver_Name= value; }
        }
        public DriverData DriverData { get; set; }
        public int TerminalKey 
        {
            get { return _Payroll_Order.Trmnl_Key; }
            set { _Payroll_Order.Trmnl_Key= value; }
        }
        public int TerminalGroupKey 
        {
            get { return _Payroll_Order.TrmnlGrp_Key; }
            set { _Payroll_Order.TrmnlGrp_Key= value; }
        }
        public DateTime DeliveryDate 
        {
            get { return _Payroll_Order.Delivery_Date; }
            set { _Payroll_Order.Delivery_Date= value; }
        }
        public string CustomerLocation 
        {
            get { return _Payroll_Order.CustLoc_Description; }
            set { _Payroll_Order.CustLoc_Description = value; }
        }
        public int? CustomerLocationKey 
        {
            get { return _Payroll_Order.Ord_CustLoc_Key; }
            set { _Payroll_Order.Ord_CustLoc_Key = value; }
        }
        public bool? IsCredited 
        {
            get { return _Payroll_Order.Credits; }
            set { _Payroll_Order.Credits = value; }
        }
        public string InvoiceNumber 
        {
            get { return _Payroll_Order.Ord_Inv_No; }
            set { _Payroll_Order.Ord_Inv_No = value; }
        }
        public string TermianlGroupDesc 
        {
            get { return _Payroll_Order.TrmnlGrp_Description; }
            set { _Payroll_Order.TrmnlGrp_Description = value; }
        }
    }
    

    那么你可以在这里改变你的功能,所以你只需要选择'new SalesItem(o, driver)':

     private void GetInformation(object sender, SelectionChangedEventArgs e)
        {
            ComboBox currentItem = sender as ComboBox;
            int driverKey = Convert.ToInt32(currentItem.SelectedValue);
            DriverData driver = new DriverData();
            driver.SetDriverData(driverKey);
            int years = driver.ServiceYears;
            List<SalesItem> items =  (from o in transportationDb._Payroll_Orders
                                     where o.Ord_Driver_Key == driverKey &&
                                     o.Delivery_Date >= new DateTime(2016, 5, 2) &&
                                     o.Delivery_Date <= new DateTime(2016, 5, 8)
                                     select new SalesItem(o, driver)).ToList();
    
            dataGrid.ItemsSource = items;
    
        }
    

    【讨论】:

    • 谢谢,我现在没时间看,但我会在几个小时后看。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-04
    • 2010-10-01
    • 2010-10-11
    • 1970-01-01
    • 2011-12-07
    相关资源
    最近更新 更多