我正在开发我的第一个WPF浏览器应用程序。
我在dataGrid中加载发票,然后使用textBox或comboBox进行过滤。
因为加载需要几秒钟,我试图根据以下示例设置加载动画:
我第一次导航到该页面时无法正常工作。我的dataGrid仍然是空的。当我调试时,我在Get()函数中的查询中发生了以下错误。
' System.Data.Entity.Core.EntityCommandExecutionException'发生在mscorlib.dll中但未在用户代码中处理
但是在我对动画进行更改之前,此查询过去一直运行良好。所以问题可能不是来自查询。
异常:抛出:"连接必须有效且开放。" (System.InvalidOperationException) 抛出了System.InvalidOperationException:"连接必须有效且打开。" 时间:2015年11月20日下午12:36:31 线程:工作者线程[13324]
public class ConsultInvoiceViewModel : ViewModelBase
{
public Context ctx = new Context();
private ICollectionView _dataGridCollection;
private string _filterString;
private ObservableCollection<Invoice> invoiceCollection;
public ConsultInvoiceViewModel()
{
if (!WPFHelper.IsInDesignMode)
{
var tsk = Task.Factory.StartNew(InitialStart);
tsk.ContinueWith(t => { MessageBox.Show(t.Exception.InnerException.Message); }, CancellationToken.None, TaskContinuationOptions.OnlyOnFaulted, TaskScheduler.FromCurrentSynchronizationContext());
}
}
private void InitialStart()
{
try
{
State = StateEnum.Busy;
DataGridCollection = CollectionViewSource.GetDefaultView(Get());
DataGridCollection.Filter = new Predicate<object>(Filter);
GetShop(); //load one comboBox
GetSupplier(); //load one comboBox
}
finally
{
State = StateEnum.Idle;
}
}
private ObservableCollection<Invoice> Get()
{
DateTime date2 = DateTime.Now.AddMonths(-2);
var query = ctx.Invoices
.GroupBy(x => new { x.suppInvNumber, x.shop1, x.date, x.foodSupplier })
.ToList()
.Select(i => new Invoice
{
suppInvNumber = i.Key.suppInvNumber,
shop1 = i.Key.shop1,
date = i.Key.date,
foodSupplier = i.Key.foodSupplier,
totalPrice = i.Sum(t => t.totalPrice),
})
.Where(d => d.date >= date2)
.OrderByDescending(d => d.date)
.AsQueryable();
invoiceCollection = new ObservableCollection<Invoice>(query);
return invoiceCollection;
}
public ICollectionView DataGridCollection
{
get
{
return _dataGridCollection;
}
set
{
_dataGridCollection = value;
OnPropertyChanged("DataGridCollection"); }
}
public string FilterString
{
get
{
return _filterString;
}
set
{
_filterString = value;
OnPropertyChanged("FilterString");
FilterCollection();
}
}
public static readonly PropertyChangedEventArgs StateArgs = ViewModelBase.CreateArgs<ConsultInvoiceViewModel>(c => c.State);
private StateEnum _State;
public StateEnum State
{
get
{
return _State;
}
set
{
var oldValue = State;
_State = value;
if (oldValue != value)
{
OnStateChanged(oldValue, value);
OnPropertyChanged(StateArgs);
}
}
}
protected virtual void OnStateChanged(StateEnum oldValue, StateEnum newValue)
{
}
private void FilterCollection()
{
if (_dataGridCollection != null)
{
_dataGridCollection.Refresh();
}
}
private bool Filter(object obj)
{
var data = obj as Invoice;
if (data != null)
{
if (!string.IsNullOrEmpty(_filterString))
{
return data.suppInvNumber.Contains(_filterString);
}
return true;
}
return false;
}
private void SearchFilter()
{
IOrderedEnumerable<Invoice> invs;
invs = ctx.Invoices
.Where(s => s.shop == Shop && s.supplier == Supplier && s.date >= From && s.date <= To)
.GroupBy(x => new {x.suppInvNumber, x.shop1, x.date, x.foodSupplier })
.ToList()
.Select(i => new Invoice
{
suppInvNumber = i.Key.suppInvNumber,
shop1 = i.Key.shop1,
date = i.Key.date,
foodSupplier = i.Key.foodSupplier,
totalPrice = i.Sum(t => t.totalPrice),
})
.OrderByDescending(d => d.date);
}
invoiceCollection.Clear();
if (invs != null)
foreach (var inv in invs)
{
invoiceCollection.Add(inv);
}
FilterCollection();
}
#region combobox
private void GetShop()
{
ctx.shops.ToList().ForEach(shop => ctx.shops.Local.Add(shop));
SShop = ctx.shops.Local;
}
private void GetSupplier()
{
ctx.foodSuppliers.ToList().ForEach(supplier => ctx.foodSuppliers.Local.Add(supplier));
FoodSupplier = ctx.foodSuppliers.Local;
}
private IList<foodSupplier> supplier;
public IList<foodSupplier> FoodSupplier
{
get
{
if (supplier == null)
GetSupplier();
return supplier;
}
set
{
supplier = value;
OnPropertyChanged("FoodSupplier");
}
}
private IList<shop> shop;
public IList<shop> SShop
{
get
{
return shop;
}
set
{
shop = value;
OnPropertyChanged("SShop");
}
}
private int _shop;
public int Shop
{
get
{
return _shop;
}
set
{
_shop = value;
OnPropertyChanged("Shop");
SearchFilter();
}
}
private int _supplier;
public int Supplier
{
get
{
return _supplier;
}
set
{
_supplier = value;
OnPropertyChanged("Supplier");
SearchFilter();
}
}
#endregion
#region "Command"
private ICommand searchCommand;
public ICommand SearchCommand
{
get
{
return searchCommand ?? (searchCommand = new RelayCommand(p => this.Search(), p => this.CanSearch()));
}
}
private bool CanSearch()
{
return true;
}
#endregion
}
答案 0 :(得分:2)
您获得的异常表示连接到数据库时出错。由于您在应用程序生命周期中保留单个Context引用的方式,因此很难对此进行诊断。这种联系可能在任何时候都失败了。
尝试在新的Context中为这样的每个逻辑操作包装数据访问。在应用程序的生命周期中保留一个上下文是一种反模式,可能导致各种错误,尤其是在尝试在后台执行操作时。
private ObservableCollection<Invoice> Get()
{
using (var ctx = new Context())
{
DateTime date2 = DateTime.Now.AddMonths(-2);
var query = ctx.Invoices
.GroupBy(x => new { x.suppInvNumber, x.shop1, x.date, x.foodSupplier })
.ToList()
.Select(i => new Invoice
{
suppInvNumber = i.Key.suppInvNumber,
shop1 = i.Key.shop1,
date = i.Key.date,
foodSupplier = i.Key.foodSupplier,
totalPrice = i.Sum(t => t.totalPrice),
})
.Where(d => d.date >= date2)
.OrderByDescending(d => d.date)
.AsQueryable();
invoiceCollection = new ObservableCollection<Invoice>(query);
}
return invoiceCollection;
}