我在WP7(Mango)上使用C#。我尝试使用特殊查询,因为我收到错误:
方法'Int32 orderBirthday(System.DateTime)'不受支持 转换为SQL。
是的,我知道...... Linq不能使用我的功能,但我不知道正确的方法......
我有一个包含name
和birthday
列的数据库表。在我的查询中,我将计算下一个生日的天数(来自所有项目),然后我将以“降序”命令。
static int orderBirthday(DateTime Birthday)
{
DateTime today = DateTime.Today;
DateTime birthday = Birthday;
DateTime next = new DateTime(today.Year, birthday.Month, birthday.Day);
if (next < today)
next = next.AddYears(1);
int numDays = (next - today).Days;
// No Conversion
return numDays;
}
public void LoadCollectionsFromDatabase()
{
DateTime today = DateTime.Today;
var toDoItemsInDB = from ToDoItem todo in toDoDB.Items
let daysToBirthday = orderBirthday(todo.ItemDate)
orderby daysToBirthday ascending
select todo;
// Query the database and load all to-do items.
AllToDoItems = new ObservableCollection<ToDoItem>(toDoItemsInDB);
.
.
.
}
答案 0 :(得分:1)
您必须从数据库中提取所有内容并在本地对其进行排序(如Enigmativity),或者找到一种在LINQ语句本身中表达排序操作的方法。由于您将排序行为提取到自己的函数中,因此您可能希望重用此逻辑。在这种情况下,最好的办法是创建一个过滤IQueryable
。
以下是如何执行此操作的示例:
public static IOrderedQueryable<Item> OrderByBirthday(
this IQueryable<Item> items)
{
return
from item in items
let today = DateTime.Today
let birthday = item.ItemDate
let next = new DateTime(today.Year, birthday.Month, birthday.Day)
let next2 = next < today ? next.AddYears(1) : next
orderby (next - today).Days
select item;
}
您可以按如下方式使用该方法:
var toDoItemsInDB = OrderByBirthday(toDoDB.Items);
或者您可以将其用作扩展方法:
var toDoItemsInDB = toDoDB.Items.OrderByBirthday();
答案 1 :(得分:0)
如果你这样做很容易:
var toDoItemsInDB = from ToDoItem todo in toDoDB.Items.ToArray()
let daysToBirthday = orderBirthday(todo.ItemDate)
orderby daysToBirthday ascending
select todo.;
请注意.ToArray()
添加到Items
。你基本上把结果带到了内存中,你的功能可以起作用。
答案 2 :(得分:0)
两种方式:
一:使用ToEnumerable()
将其从Linq2SQL拉到Linq2Object,然后在C#级别使用orderBirthday
。
优点是代码和维护简单,缺点是 效率低(取决于你正在做什么。
二:在SQL中编写一个等效函数,假设它被称为dbo.orderBirthday
。使您的orderBirthday
方法成为datacontext派生类的非静态方法,然后将您的方法标记为具有等效的SQL函数:
[Function(Name="dbo.orderBirthday",IsComposable=true)] //IsComposable is true for functions that can be used within queries, false for stored procedures that must be called on their own.
public int OrderBirthday([Parameter(Name="@birthday",DbType="datetime") DateTime birthday)
{
return Helper.OrderBirthday(birthday); // just to show that we can keep the static version around if we want and call into it. Alternatively we could just move the whole body here.
}
这里C#代码用于非Linq2SQL上下文,SQL代码用于在Linq2SQL上下文中编写SQL查询。
优点:可以在SQL中保持更长时间。缺点:同一方法的两个版本可能会失去同步并导致错误。
也可以让C#代码始终调用SQL代码:
[Function(Name="dbo.orderBirthday",IsComposable=true)]
public int OrderBirthday([Parameter(Name="@birthday",DbType="datetime") DateTime birthday)
{
return (int)ExecuteMethodCall(this, (MethodInfo)MethodInfo.GetCurrentMethod(), birthday).ReturnValue;
}
优点:保留一个版本(SQL)作为唯一版本,因此它不会与C#版本不同步。缺点:即使在处理与SQL无关的对象时也要调用SQL。
答案 3 :(得分:0)
如果您不想加载内存中的所有项目,并且希望数据库执行计算,则可以编写一个可以执行复杂计算的存储过程,并使用ADO或EF调用该过程。