考虑IEnumerable扩展方法SingleOrDefault()
和FirstOrDefault()
返回序列的唯一元素,如果序列为空,则返回默认值; 如果序列中有多个元素,则此方法抛出异常.
而FirstOrDefault
从MSDN(推测当使用OrderBy()
或 OrderByDescending()
或根本没有),
返回序列的第一个元素
考虑一些示例查询,并不总是清楚何时使用这两种方法:
var someCust = db.Customers
.SingleOrDefault(c=>c.ID == 5); //unlikely(?) to be more than one, but technically COULD BE
var bobbyCust = db.Customers
.FirstOrDefault(c=>c.FirstName == "Bobby"); //clearly could be one or many, so use First?
var latestCust = db.Customers
.OrderByDescending(x=> x.CreatedOn)
.FirstOrDefault();//Single or First, or does it matter?
Run Code Online (Sandbox Code Playgroud)
题
你遵循或暗示什么约定决定要使用时SingleOrDefault()
,并FirstOrDefault()
在您的LINQ查询?
我经常看到人们使用Where.FirstOrDefault()
搜索并抓住第一个元素.为什么不用Find()
?对方是否有优势?我无法区分.
namespace LinqFindVsWhere
{
class Program
{
static void Main(string[] args)
{
List<string> list = new List<string>();
list.AddRange(new string[]
{
"item1",
"item2",
"item3",
"item4"
});
string item2 = list.Find(x => x == "item2");
Console.WriteLine(item2 == null ? "not found" : "found");
string item3 = list.Where(x => x == "item3").FirstOrDefault();
Console.WriteLine(item3 == null ? "not found" : "found");
Console.ReadKey();
}
}
}
Run Code Online (Sandbox Code Playgroud) 通过主键选择多个实体的最有效方法是什么?
public IEnumerable<Models.Image> GetImagesById(IEnumerable<int> ids)
{
//return ids.Select(id => Images.Find(id)); //is this cool?
return Images.Where( im => ids.Contains(im.Id)); //is this better, worse or the same?
//is there a (better) third way?
}
Run Code Online (Sandbox Code Playgroud)
我意识到我可以做一些性能测试来比较,但我想知道是否实际上有比两者更好的方法,并且我正在寻找一些启示,这两个查询之间的区别是,如果有的话,一旦它们一直存在"翻译".
到目前为止,我所获得的代码运行良好
public async Task<ActionResult> Details(Guid? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
ItemDetailModel model = new ItemDetailModel();
model.Item = await db.Items.FindAsync(id);
if (model.Item == null)
{
return HttpNotFound();
}
return View(model);
}
Run Code Online (Sandbox Code Playgroud)
但是我想要包含1个表并且不能使用 FindAsync
public async Task<ActionResult> Details(Guid? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
ItemDetailModel model = new ItemDetailModel();
model.Item = await db.Items.Include(i=>i.ItemVerifications).FindAsync(id);
if (model.Item == null)
{
return HttpNotFound();
}
return View(model);
}
Run Code Online (Sandbox Code Playgroud)
所以我面临这个错误
严重级代码描述项目文件行抑制状态错误CS1061'IQueryable'不包含'FindAsync'的定义,并且没有扩展方法'FindAsync'可以找到接受类型'IQueryable'的第一个参数(你是否缺少using指令或装配参考?)
有任何线索如何修复它?
当与数组一起使用时,编译器将foreach
循环编译成类似for
循环的循环foreach
.并且当与or一起使用时,编译器将foreach
循环编译成类似while
循环的循环.那么这是否是纯粹?或者有什么复杂的东西吗?foreach
IEnumerable
IEnumerable<T>
foreach
syntactic sugar
CLR知道foreach
吗?foreach
在MSIL代码中是否有专门设计的内容?
我试图在仅限于特定类型的泛型类上定义一个方法。我想出了这个:
interface IHasId
{
int Id { get; }
}
public class Foo<T>
{
private List<T> children;
public IHasId GetById(int id)
{
foreach (var child in children.Cast<IHasId>())
{
if (child.Id == id)
{
return child;
}
}
return null;
}
}
Run Code Online (Sandbox Code Playgroud)
它会起作用,但看起来像代码味道......似乎应该有一种方法让编译器强制执行此操作。就像是:
public class Foo<T>
{
public IHasId GetById<TWithId>(int id) where TWithId : IHasId {}
}
Run Code Online (Sandbox Code Playgroud)
或者,甚至更好:
public class Foo<T>
{
public IHasId GetById(int id) where T : IHasId {}
}
Run Code Online (Sandbox Code Playgroud)
我看到了一些与 Java 相关的帖子,其中一篇专门讨论了将 T 限制为枚举,但没有直接说到重点。
https://learn.microsoft.com/en-us/aspnet/core/tutorials/first-mvc-app/details
在 Microsoft 文档示例中,
在和.FirstOrDefaultAsync()
中使用;
用于. 我想知道这是为什么?Detail
Delete
GET
.FindAsync()
DeleteConfirmed
任何人都可以告诉我何时使用Find()和何时使用First()?如果您只是想要一个简单的查询来查找列表中的特定项目,那么一个比另一个好吗?
像这样的班级
Public Class ItemPanel
Inherits Panel
Public Name as string
Public Quantity As Integer
End Class
Run Code Online (Sandbox Code Playgroud)
像这样的清单
Public li_ip As New List(Of ItemPanel)
Run Code Online (Sandbox Code Playgroud)
我有一个子菜单可以帮助我在单击按钮时将ItemPanel添加到li_ip列表中,单击的每个按钮也会将其文本添加到li_item中,因此,当按钮单击两次时,只有第一次将ItemPanel添加到li_ip中,第二次单击只会更改ItemPanel中的数量
Private Sub RefreshOrdered(sender As Object)
If Not li_item.Contains(sender.Text) Then
Dim pn As ItemPanel
With pn
.Name = sender.Text
.Quantity = 1
End With
li_ip.Add(pn)
Else
'Here I want to change the quantity in ItemPanel depend on the sender.Text
End If
End Sub
Run Code Online (Sandbox Code Playgroud)
那么如何获得想要的结果?我还要写些什么?
我需要检查 FirstOrDefault() 是否不为空,如果不为空,则获取一些属性。我最好的选择是:
var results = Database.Set<Pizzas>().Select(x => new PizzaViewModel
{
Base = Database.Set<Bases>().FirstOrDefault(y => y.Id == x.Base.Id) != null ? Database.Set<Bases>().FirstOrDefault(y => y.Id == x.Base.Id).Name : null
}).ToList();
Run Code Online (Sandbox Code Playgroud)
有更好的方法吗?