Linq to SQL:.FirstOrDefault()不适用于选择新的{...}

时间:2008-10-14 16:12:46

标签: linq linq-to-sql

我刚问this question。这引出了一个新问题:)

到目前为止,我使用了以下使用Linq to SQL选择内容的模式,目的是能够处理查询返回的0“行”:

var person = (from p in [DataContextObject].Persons
              where p.PersonsID == 1
              select new p).FirstOrDefault();

if (person == null)
{
    // handle 0 "rows" returned.
}

但是当我这样做时,我无法使用FirstOrDefault()

var person = from p in [DataContextObject].Persons
             where p.PersonsID == 1
             select new { p.PersonsID, p.PersonsAdress, p.PersonsZipcode };

// Under the hood, this pattern generates a query which selects specific
// columns which will be faster than selecting all columns as the above
// snippet of code does. This results in a performance-boost on large tables.

如何使用第二种模式检查查询返回的0“行”?



更新:

我认为我的构建失败了,因为我试图将查询结果分配给使用this._user类型声明的变量([DataContext].User)。

this._user = (from u in [DataContextObject].Users
              where u.UsersID == [Int32]
              select new { u.UsersID }).FirstOrDefault();

编译错误:无法将“AnonymousType#1”类型隐式转换为“[DataContext] .User”。

关于如何解决这个问题的任何想法?我是否必须制作自己的对象?

5 个答案:

答案 0 :(得分:13)

为什么你能继续做同样的事情?它给你一个错误吗?

var person = (from p in [DataContextObject].Persons
              where p.PersonsID == 1
              select new { p.PersonsID, p.PersonsAdress, p.PersonsZipcode }).FirstOrDefault();

if (person == null) {    
    // handle 0 "rows" returned.
}

它仍然是一个像实际对象一样的引用对象,它只是匿名的,因此在编译代码之前你不知道实际的类型。

答案 1 :(得分:2)

<强>更新

  

我现在看到你实际询问的是什么!对不起,我的回答不再适用。当它是空的时我以为你没有得到空值。接受的响应是正确的,如果要使用超出范围的对象,则需要创建一个新类型并使用New MyType(...)。我知道DevEx的RefactorPro对此进行了重构,我认为resharper也是如此。

像这样调用.FirstOrDefault(null):

string[] names = { "jim", "jane", "joe", "john", "jeremy", "jebus" };
var person = (
    from p in names where p.StartsWith("notpresent") select 
        new { Name=p, FirstLetter=p.Substring(0,1) } 
    )
    .DefaultIfEmpty(null)
    .FirstOrDefault();

MessageBox.Show(person==null?"person was null":person.Name + "/" + person.FirstLetter);

这对我有用。

答案 2 :(得分:1)

if (person.Any()) /* ... */;

OR

if (person.Count() == 0) /* ... */;

答案 3 :(得分:1)

关于您的更新:您必须创建自己的类型,将this._user更改为 int ,或者选择整个对象,而不仅仅是特定的列。

答案 4 :(得分:0)

您仍然可以使用FirstOrDefault。只是

var PersonFields = (...).FirstOrDefault()  

PersonFields将为null或具有您创建的属性的对象。