SQL到LINQ查询,其中where子句中的日期无效
本文关键字:子句 日期 无效 where 其中 LINQ 查询 SQL | 更新日期: 2023-09-27 18:14:10
我尝试通过LINQ查询数据库项,但它不起作用。例外只是:
对象引用未设置为对象的实例。
堆栈竞争和异常本身一样毫无帮助:
在SQLite。表查询
1.CompileExpr(Expression expr, List
1queryArgs(,位于SQLite。表查询1.CompileExpr(Expression expr, List
1 queryArgs(d: ''XX''XX''XX''XX''SQLite.cs:line 2388SQLite。表查询1.CompileExpr(Expression expr, List
1 queryArgs(d: ''XX''XX''XX''XX''SQLite.cs:line 2308SQLite。表查询1.CompileExpr(Expression expr, List
1 queryArgs(d: ''XX''XX''XX''XX''SQLite.cs:line 2308SQLite。表查询1.CompileExpr(Expression expr, List
1 queryArgs(d: ''XX''XX''XX''XX''SQLite.cs:line 2308SQLite。中的TableQuery1.GenerateCommand(String selectionList) in d:'XX'XX'XX'XX'XX'SQLite.cs:line 2274 at SQLite.TableQuery
1.GetEnumerator((d: ''XX''XX''XX''XX''SQLite.cs:line 2521系统集合。通用的列出1..ctor(IEnumerable
1集合(
在系统中。林克。可枚举。ToList[TSource](IEnumerable`1源(位于Kapital。数据模型。DataManagerOnetimeExpense<>c_DisplayClass5.b_4((在d:''XX''XX''XX''XX''DataModel''DataManagerOnetimeExpense.cs:line 47
在SQLite。SQLiteConnection。中的RunInTransaction(操作操作(d: ''XX''XX''XX''XX''SQLite.cs:line 906 atKapital。数据模型。DataManagerOnetimeExpense。RetrieveItems(Int32个月,Int32年,布尔值isPayed(d: ''XX''XX''XX ''XX''DataModel''DataManagerOnetimeExpense.cs:line 39 atUnitTestKapital。数据库TestDataManager一次性支出。TestRetrieveItemsByMonthYearIsPaid((在里面d: ''XX''XX''XX''XX''UnitTestKapital''Database''TestDataManagerOnetimeExpense.cs:line154
然而,以下是LINQ查询:
public List<OnetimeExpense> RetrieveItems(int month, int year, bool isPaid)
{
var onetimeExpenses = new List<OnetimeExpense>();
connection.RunInTransaction(() =>
{
var items = from s in connection.Table<OnetimeExpense>()
let convertedDate = (DateTime)s.PaymentDate
where (convertedDate.Month == month)
&& (convertedDate.Year == year)
&& (s.IsPaid == isPaid)
select s;
onetimeExpenses = items.ToList();
});
return onetimeExpenses;
}
它肯定与日期有关,因为以下方法正在起作用(基本上与没有日期的方法相同(:
public List<OnetimeExpense> RetrieveItems(bool isPaid)
{
var onetimeExpenses = new List<OnetimeExpense>();
connection.RunInTransaction(() =>
{
var items = from s in connection.Table<OnetimeExpense>()
where (s.IsPaid == isPaid)
select s;
onetimeExpenses = items.ToList();
});
return onetimeExpenses;
}
有趣的是:几个月前,我在WinRT应用程序上遇到了同样的问题。我设法用上面显示的方法解决了这个问题。
我使用的是SQLite 3.7.16.2。LINQ提供程序是sqlite net。
还有什么?Visual Studio 2012,C#。净额4.5。这是一个WPF应用程序。
编辑:这是我的数据对象,它是一个简单的POCO。PaymentDate是用DateTime初始化的。今天,因此永远不会无效。
public class OnetimeExpense : NotifyPropertyChanged
{
/**
* int Id
* string Name
* DateTime PaymentDate
* decimal Amount
* Boolean IsPaid
* */
#region getters and setters
private int id;
[PrimaryKey, AutoIncrement]
public int Id
{
get { return id; }
set
{
this.id = value;
this.OnPropertyChanged("Id");
}
}
private DateTime paymentDate = DateTime.Today;
public DateTime PaymentDate
{
get { return this.paymentDate; }
set
{
paymentDate = value;
this.OnPropertyChanged("PaymentDate");
}
}
private bool isPaid;
public bool IsPaid
{
get { return this.isPaid; }
set
{
this.isPaid = value;
this.OnPropertyChanged("IsPaid");
}
}
#endregion
#region Constructor
public OnetimeExpense(string name, decimal amount, DateTime paymentDate, bool isPaid)
{
this.name = name;
this.paymentDate = paymentDate;
this.amount = amount;
this.isPaid = isPaid;
}
public OnetimeExpense()
{
}
#endregion
}
第2版Gert Arnold建议使用此解决方案。它正在工作,而且据我所知,它的性能比我的查询要好。尽管如此,我还是想知道上面的查询出了什么问题。
public List<OnetimeExpense> RetrieveItems(int month, int year, bool isPaid)
{
var onetimeExpenses = new List<OnetimeExpense>();
var lowerBound = new DateTime(year, month, 1);
var upperBound = lowerBound.AddMonths(1);
connection.RunInTransaction(() =>
{
var items = from s in connection.Table<OnetimeExpense>()
where s.PaymentDate >= lowerBound
&& s.PaymentDate < upperBound
&& s.IsPaid == isPaid
select s;
onetimeExpenses = items.ToList();
});
return onetimeExpenses;
}
这不是一个直接的解决方案,但您可以通过不同的过滤方式来规避这个问题。假设您要筛选2013年5月的记录:
var lowerBound = new DateTime(2013,5,1);
var upperBound = new DateTime(2013,6,1);
var items = from s in connection.Table<OnetimeExpense>()
where s.PaymentDate >= lowerBound
&& s.PaymentDate < upperBound
&& s.IsPaid == isPaid
select s;
这不仅仅是回避问题。当PaymentDate
上有索引时,它还有可能使查询更加高效。像convertedDate.Year
这样的表达式被翻译成DATEPART(Year, [t0].[PaymentDate])
。这样的表达式是不可搜索的,即数据库引擎不能使用索引进行查找。
if (LoggingFilter.StartDate.HasValue)
{
logs = auditlogs.Where(x => x.DateTime > auditLoggingFilter.StartDate).ToList();
}
if (LoggingFilter.EndDate.HasValue)
{
LoggingFilter.EndDate = LoggingFilter.EndDate.Value.AddTicks(DateTime.Now.TimeOfDay.Ticks);
logs = auditlogs.Where(x => x.DateTime < LoggingFilter.EndDate).ToList();
}
这对我有用。