最近我遇到了这个问题,花了一些时间才弄明白。我有这样的代码:
private Member FindMemberByName(string name)
{
var member =
this.db.Members.AsEnumerable()
.Where(d => d.ShortName == name)
.DefaultIfEmpty(this.CreateNewMember(name))
.First();
return member;
}
private Member CreateNewMember(string name)
{
return this.db.Members.Add(new Member { Name = name });
}
我希望FindMemberByName()返回现有实体,如果缺席,则创建新实体并返回一个实体。
但是我注意到,即使传递了现有名称,也会调用CreateNewMember()。
答案 0 :(得分:4)
您询问的行为与LINQ无关。您在DefaultIfEmpty()参数列表中放置的方法将在调用DefaultIfEmpty()之前进行评估。您可以通过编写一个类似的方法来看到这一点,该方法不会引用传入的默认对象。
void Main()
{
CalledMethod(CreateDefault("Hello World"));
}
void CalledMethod<TSource>(TSource defaultValue)
{
}
TestClass CreateDefault(string message)
{
return new TestClass() { Message = message, };
}
public class TestClass
{
public string Message { get; set; } = null;
public TestClass() { }
}
答案 1 :(得分:3)
稍微调试一下后我就明白,即使没有调用DefaultIfEmpty()
方法,也会立即评估First()
参数的值。所以实际上它是在了解生成的IEnumerable是否为空之前进行评估的。
我花了几个小时试图找出问题所在。希望这可以帮助其他人节省相同的时间: - )