我有一个包含许多点(具有X和Y分量)的列表。
我想要获取列表中所有点的最大X值,如下所示:
double max = pointList.Max(p=> p.X);
问题是当列表中存在 null 而不是 point 时。如何最好地解决这个问题?
好的,你可以直接将它们过滤掉:
pointList.Where(p => p != null).Max(p => p.X)
另一方面,如果你想将null
视为具有X坐标0
(或类似)的点来处理,你可以这样做:
pointList.Max(p => p == null ? 0 : p.X)
请注意,这两种技术都会在序列为空时引发异常。如果需要的话,一个解决方法是:
pointList.DefaultIfEmpty().Max(p => p == null ? 0 : p.X)
如果你想要为一个空指针的X属性提供默认值:
pointList.Max(p => p == null ? 0 : p.X)
或者为一个空列表提供默认值:
int max = points.Where(p => p != null)
.Select(p => p.X)
.DefaultIfEmpty()
.Max();
DefaultIfEmpty
应用于结果类型。 - Ani在这种情况下,我不建议使用DefaultIfEmpty
,因为它会产生比其他替代方案更大的SQL。
请看这个例子:
我们有一个页面模块的列表,并想获取列"Sort"的最大值。如果该列表没有记录,则返回null。 DefaultIfEmpty
检查是否为null,并在该列为null时返回列数据类型的默认值。
var max = db.PageModules.Where(t => t.PageId == id).Select(t => t.Sort).DefaultIfEmpty().Max();
exec sp_executesql N'SELECT
[GroupBy1].[A1] AS [C1]
FROM ( SELECT
MAX([Join1].[A1]) AS [A1]
FROM ( SELECT
CASE WHEN ([Project1].[C1] IS NULL) THEN 0 ELSE [Project1].[Sort] END AS [A1]
FROM ( SELECT 1 AS X ) AS [SingleRowTable1]
LEFT OUTER JOIN (SELECT
[Extent1].[Sort] AS [Sort],
cast(1 as tinyint) AS [C1]
FROM [dbo].[PageModules] AS [Extent1]
WHERE [Extent1].[PageId] = @p__linq__0 ) AS [Project1] ON 1 = 1
) AS [Join1]
) AS [GroupBy1]',N'@p__linq__0 int',@p__linq__0=11
go
Convert.ToInt32()
处理null值,那么代码如下:var max = Convert.ToInt32(db.PageModules.Where(t => t.PageId == id).Max(t => (int?)t.Sort));
然后我们得到以下SQL语句:
exec sp_executesql N'SELECT
[GroupBy1].[A1] AS [C1]
FROM ( SELECT
MAX([Extent1].[Sort]) AS [A1]
FROM [dbo].[PageModules] AS [Extent1]
WHERE [Extent1].[PageId] = @p__linq__0
) AS [GroupBy1]',N'@p__linq__0 int',@p__linq__0=11
go
我强烈推荐使用ExpressProfiler来检查执行的SQL语句:http://expressprofiler.codeplex.com/
最后一个Linq表达式也可以写成:
var max = Convert.ToInt32(db.PageModules.Where(t => t.PageId == id).Select(t => (int?)t.Sort).Max());
这将产生相同的SQL代码,但我更喜欢更简洁的.Max(t => (int?)t.Sort)
。
Convert.ToInt32((from x in table join y in table 2 on x.ID equals y.ID where y.ProjectID == ProjectID select x.ObservationNum).Max());
是否有一种方法可以使用您的语法进行连接,或修改我的方法以获得可空int转换? - Paul Gibsondouble max = pointList.Max(p=>(double?)p.X) ?? 0;
double max = pointList.Where(p=>p != null).Max(p=>p.X)
检查 null 对我没用,我使用了 DefaultIfEmpty()。
int max_sequence = _dbContext.myTable
.Where(e=>e.field1==param.field1
&& e.fieldDate==param.fieldDate
)
.Select(e => e.Sequence)
.DefaultIfEmpty()
.Max();
具有最大值的可空列如下所示
var maximum = objectEntity.where(entity => entity.property != null).max(entity => entity.property.HasValue);
上述语句返回实体属性的最大数量
double? maxOrNull = pointList.
.Where(p => p != null)
.OrderByDescending(p => p.x)
.FirstOrDefault();
double max = 0;
if (maxOrNull.HasValue) max = maxOrNull.Value;
这将适用于内存列表和Linq2Sql,并且可能也很高效。
DefaultIfEmpty
。请查看我的答案以了解原因:链接 - NikkelmannpointList.Max(p => p == null ? (double?)null : p.X)
。请注意,使用可空类型时,即使是空序列,Max
也不会抛出异常。 - Jeppe Stig Nielsen