对于数据库集合,FirstOrDefault应该返回null吗?

时间:2016-09-02 01:32:16

标签: linq

我对在数据库上运行的LINQ方法SingleOrDefaultFirstOrDefaultLastOrDefaultElementAtOrDefault方法的预期行为或系列感到困惑。

他们应该回来:

  1. null或
  2. 使用默认值填充的新对象?

3 个答案:

答案 0 :(得分:1)

如果序列为空,它们将返回序列中的项目或项目的sum(grepl(', 12:00:00 AM', col)) > 0值(如果指定的索引超出范围,则返回'ElementAtOrDefault')。

以下摘录摘自default的文档:

  

解决方案是使用default关键字,它将返回null   引用类型,数值类型为零。对于结构,它会   返回结构的每个成员初始化为零或取决于   关于它们是价值还是参考类型。

指向default文档的链接:https://msdn.microsoft.com/en-us/library/xwth0h0d.aspx

答案 1 :(得分:0)

来自Enumerable.FirstOrDefault

返回值部分
  如果 source 为空,则

默认(TSource);否则, source 中的第一个元素。

Reference Types的{p> default(T)在几乎所有情况下都为空,但Value Types不为空。例子:

int i; // 0
var j = default(int);    // 0
var b = default(bool);   // false
var s = default(string); // null
var s = default(object); // null

var i0 = (new    int[] { }).FirstOrDefault(); // 0 
var s0 = (new string[] { }).FirstOrDefault(); // null

还有DefaultIfEmpty

var i1 = new int[] { }.DefaultIfEmpty(-1).ToArray(); // { -1 }

答案 2 :(得分:0)

以下是使用反射器的一些定义。

<强> FirstOrDefault

public static TSource FirstOrDefault<TSource>(this IEnumerable<TSource> source)
{
    if (source == null)
    {
        throw Error.ArgumentNull("source");
    }
    IList<TSource> list = source as IList<TSource>;
    if (list != null)
    {
        if (list.Count > 0)
        {
            return list[0];
        }
    }
    else
    {
        using (IEnumerator<TSource> enumerator = source.GetEnumerator())
        {
            if (enumerator.MoveNext())
            {
                return enumerator.Current;
            }
        }
    }
    return default(TSource);
}

<强>的SingleOrDefault

    public static TSource SingleOrDefault<TSource>(this IEnumerable<TSource> source)
    {
        if (source == null)
        {
            throw Error.ArgumentNull("source");
        }
        IList<TSource> list = source as IList<TSource>;
        if (list != null)
        {
            switch (list.Count)
            {
                case 0:
                    return default(TSource);

                case 1:
                    return list[0];
            }
        }
        else
        {
            using (IEnumerator<TSource> enumerator = source.GetEnumerator())
            {
                if (!enumerator.MoveNext())
                {
                    return default(TSource);
                }
                TSource current = enumerator.Current;
                if (!enumerator.MoveNext())
                {
                    return current;
                }
            }
        }
        throw Error.MoreThanOneElement();
    }

<强> LastOrDefault

    public static TSource LastOrDefault<TSource>(this IEnumerable<TSource> source)
    {
        if (source == null)
        {
            throw Error.ArgumentNull("source");
        }
        IList<TSource> list = source as IList<TSource>;
        if (list != null)
        {
            int count = list.Count;
            if (count > 0)
            {
                return list[count - 1];
            }
        }
        else
        {
            using (IEnumerator<TSource> enumerator = source.GetEnumerator())
            {
                if (enumerator.MoveNext())
                {
                    TSource current;
                    do
                    {
                        current = enumerator.Current;
                    }
                    while (enumerator.MoveNext());
                    return current;
                }
            }
        }
        return default(TSource);
    }

<强> ElementAtOrDefault

public static TSource ElementAtOrDefault<TSource>(this IEnumerable<TSource> source, int index)
    {
        if (source == null)
        {
            throw Error.ArgumentNull("source");
        }
        if (index >= 0)
        {
            IList<TSource> list = source as IList<TSource>;
            if (list != null)
            {
                if (index < list.Count)
                {
                    return list[index];
                }
            }
            else
            {
                using (IEnumerator<TSource> enumerator = source.GetEnumerator())
                {
                    while (enumerator.MoveNext())
                    {
                        if (index == 0)
                        {
                            return enumerator.Current;
                        }
                        index--;
                    }
                }
            }
        }
        return default(TSource);
    }