如何在 WinForm 中使用 LINQ 或 lambda return 任务列表
How to return Task list using LINQ or lambda in WinForm
我想在我的 LINQ 函数中使用 async 和 await 函数,但我不知道如何使用。我有两个表 Order 和 Product 我想加入它们并使用 async 在 DataGridView
中弹出。
这是我的异步函数。
我的列表定义是:
List<OrderDTO> transactionByDate;
和我的函数:
private async Task<List<OrderDTO>> GetTransactionByDate(DateTime today)
{
return await Task.Factory.StartNew(() =>
{
using (Db db = new Db())
{
var totalOrder = (from u in db.Orders
join p in db.Product on u.ProductId equals p.ProductId
where u.OrderDate == today
select new OrderDTO
{
OrderId = u.OrderId,
ProductName = p.ProductName,
Date = u.OrderDate,
Price = u.Price,
}).OrderByDescending(x => x.Date).ToList();
return totalOrder;
}
});
}
然后在我的按钮事件中:
private async void button1_Click(object sender, EventArgs e)
{
transactionByDate = await GetTransactionByDate(today);
dgvTransactions.DataSource = transactionByDate;
}
我得到的错误是:
The entity or complex type 'OrderDTO' cannot be constructed in a LINQ to Entities query.
我真的不知道如何从我的异步 GetTransactionByDate(today)
函数中 return。如果你能帮助我,我将不胜感激,我是这种编码的新手。
我无法测试它,因为它不能在本地编译(显然),但我认为你可以这样做:
private async Task<List<OrderDTO>> GetTransactionByDate(DateTime today)
{
return await Task.Factory.StartNew(() =>
{
using (Db db = new Db())
{
var totalOrder = (from u in db.Orders
join p in db.Product on u.ProductId equals p.ProductId
where u.OrderDate == today
select new
{
OrderId = u.OrderId,
ProductName = p.ProductName,
Date = u.OrderDate,
Price = u.Price
})
.ToList();
var result = totalOrder.Select(ano =>
new OrderDTO
{
OrderId = ano.OrderId,
ProductName = ano.ProductName,
Date = ano.OrderDate,
Price = ano.Price,
})
.OrderByDescending(x => x.Date)
.ToList();
return result;
}
}
}
关键是要将数据库中发生的事情与内存中发生的事情分开。
不过,在你开始之前,我会创建一个很好的辅助函数,它可以去掉一些样板代码。
private async Task<List<T>> GetDtosAsync<T>(Func<Db, List<T>> getDtos) =>
await Task.Run(() =>
{
using (Db db = new Db())
{
return getDtos(db);
}
});
请注意,我使用的是 Task.Run
,因为 Task.Factory.StartNew
已过时且不再推荐。
现在你可以这样写你的方法了:
private async Task<List<OrderDTO>> GetTransactionByDate(DateTime today) =>
await GetDtosAsync(db =>
{
var query =
from u in db.Orders
join p in db.Product on u.ProductId equals p.ProductId
where u.OrderDate == today
select new
{
u.OrderId,
p.ProductName,
u.OrderDate,
u.Price,
};
var totalOrder =
query
.ToList()
.Select(x => new OrderDTO
{
OrderId = x.OrderId,
ProductName = x.ProductName,
Date = x.OrderDate,
Price = x.Price,
})
.ToList();
return totalOrder;
});
是 query.ToList()
从数据库中获取数据并将其存入内存,然后再构建最终列表。
我想在我的 LINQ 函数中使用 async 和 await 函数,但我不知道如何使用。我有两个表 Order 和 Product 我想加入它们并使用 async 在 DataGridView
中弹出。
这是我的异步函数。
我的列表定义是:
List<OrderDTO> transactionByDate;
和我的函数:
private async Task<List<OrderDTO>> GetTransactionByDate(DateTime today)
{
return await Task.Factory.StartNew(() =>
{
using (Db db = new Db())
{
var totalOrder = (from u in db.Orders
join p in db.Product on u.ProductId equals p.ProductId
where u.OrderDate == today
select new OrderDTO
{
OrderId = u.OrderId,
ProductName = p.ProductName,
Date = u.OrderDate,
Price = u.Price,
}).OrderByDescending(x => x.Date).ToList();
return totalOrder;
}
});
}
然后在我的按钮事件中:
private async void button1_Click(object sender, EventArgs e)
{
transactionByDate = await GetTransactionByDate(today);
dgvTransactions.DataSource = transactionByDate;
}
我得到的错误是:
The entity or complex type 'OrderDTO' cannot be constructed in a LINQ to Entities query.
我真的不知道如何从我的异步 GetTransactionByDate(today)
函数中 return。如果你能帮助我,我将不胜感激,我是这种编码的新手。
我无法测试它,因为它不能在本地编译(显然),但我认为你可以这样做:
private async Task<List<OrderDTO>> GetTransactionByDate(DateTime today)
{
return await Task.Factory.StartNew(() =>
{
using (Db db = new Db())
{
var totalOrder = (from u in db.Orders
join p in db.Product on u.ProductId equals p.ProductId
where u.OrderDate == today
select new
{
OrderId = u.OrderId,
ProductName = p.ProductName,
Date = u.OrderDate,
Price = u.Price
})
.ToList();
var result = totalOrder.Select(ano =>
new OrderDTO
{
OrderId = ano.OrderId,
ProductName = ano.ProductName,
Date = ano.OrderDate,
Price = ano.Price,
})
.OrderByDescending(x => x.Date)
.ToList();
return result;
}
}
}
关键是要将数据库中发生的事情与内存中发生的事情分开。
不过,在你开始之前,我会创建一个很好的辅助函数,它可以去掉一些样板代码。
private async Task<List<T>> GetDtosAsync<T>(Func<Db, List<T>> getDtos) =>
await Task.Run(() =>
{
using (Db db = new Db())
{
return getDtos(db);
}
});
请注意,我使用的是 Task.Run
,因为 Task.Factory.StartNew
已过时且不再推荐。
现在你可以这样写你的方法了:
private async Task<List<OrderDTO>> GetTransactionByDate(DateTime today) =>
await GetDtosAsync(db =>
{
var query =
from u in db.Orders
join p in db.Product on u.ProductId equals p.ProductId
where u.OrderDate == today
select new
{
u.OrderId,
p.ProductName,
u.OrderDate,
u.Price,
};
var totalOrder =
query
.ToList()
.Select(x => new OrderDTO
{
OrderId = x.OrderId,
ProductName = x.ProductName,
Date = x.OrderDate,
Price = x.Price,
})
.ToList();
return totalOrder;
});
是 query.ToList()
从数据库中获取数据并将其存入内存,然后再构建最终列表。