使用 LINQ 查询 ODataV4 连接服务 - 从 table 获取最后一条记录

Query ODataV4 connected service with LINQ - Get last record from table

我正在尝试从 C# 应用程序查询我的 OData 网络服务。

当我执行以下操作时:

var SecurityDefs = from SD in nav.ICESecurityDefinition.Take(1) 
                   orderby SD.Entry_No descending 
                   select SD;

我得到一个异常,因为 .top() 和 .orderby 不应该一起使用。

我需要获取数据集中的最后一条记录,而且只有最后一条。

目的是获取分类帐中最后使用的条目号,然后继续创建新条目以增加找到的条目号。

我似乎无法在网上找到任何解释如何执行此操作的内容。

服务仅 returns 来自 Feed 的最后一条记录非常重要,因为在此解决方案中速度至关重要。

i get an exception because .top() and .orderby is not supposed to be used together.

你在哪里读到的?一般来说.top().Take()应该ONLYWITH.orderby()一起使用,否则记录不保证检索到的是可重复的或可预测的。

可能这里的复合问题是混合了 queryfluent 表达式语法,这是有效的,但你必须理解顺序优先。
您的语法是获取 1 条记录,然后应用排序顺序...您可能会发现从 查询 开始更容易,如下所示:

// build your query
var SecurityDefsQuery = from SD in nav.ICESecurityDefinition 
                        orderby SD.Entry_No descending 
                        select SD;
// Take the first item from the list, if it exists, will be a single record.
var SecurityDefs = SecurityDefsQuery.FirstOrDefault();
// Take an array of only the first record if it exists
var SecurityDefsDeferred = SecurityDefsQuery.Take(1); 

这可以使用括号在单行上执行,但您可以看到两种情况下的查询是如何相同的,SecurityDefs 在这种情况下是单个 ICESecurityDefinition 类型的记录,其中因为 SecurityDefsDeferred 是一个只有一条记录的 IQueryable<ICESecurityDefinition>

如果你只需要记录本身,你这一张:

var SecurityDefs = (from SD in nav.ICESecurityDefinition 
                    orderby SD.Entry_No descending 
                    select SD).FirstOrDefault();

您也可以使用 fluent 表示法执行相同的查询:

var SecurityDefs = nav.ICESecurityDefinition.OrderByDescending(sd => sd.Entry_No)
                                            .FirstOrDefault();

在这两种情况下,.Take(1).top() 都是通过 .FirstOrDefault() 实现的。你已经指出速度很重要,所以使用 .First().FirstOrDefault() 而不是 .Single().SingleOrDefault() 因为单个变体实际上会请求 .Take(2) 并且会抛出一个如果 returns 1 或没有结果则例外。

The OrDefault variants on both of these queries will not impact the performance of the query itself and should have negligble affect on your code, use the one that is appriate for your logic that uses the returned record and if you need to handle the case when there is no existing record.

如果正在 returned 的记录有很多列,而您只对 Entry_No 列值感兴趣,那么也许您应该简单地查询该特定值本身:

查询表达式:

var lastEntryNo = (from SD in nav.ICESecurityDefinition 
                   orderby SD.Entry_No descending 
                   select SD.Entry_No).FirstOrDefault();

表达流畅:

var lastEntryNo = nav.ICESecurityDefinition.OrderByDescending(sd => sd.Entry_No)
                                           .Select(sd => sd.Entry_No)
                                           .FirstOrDefault();

如果 Speed 是 paramount 然后考虑在服务上提供特定的自定义端点以提供记录或不处理客户端中的“Entry_No”总而言之,让代码的工作从客户端接收数据并在插入条目时计算它。

使查询执行得更快并不是您正在寻找的灵丹妙药,即使这是高度优化的,您当前的模式也意味着 X 个客户端都可以调用该服务来获得Entry_No 的当前值,意味着它们都将从相同的值开始递增。

如果您必须客户端增加Entry_No那么您应该考虑在服务上放置一个自定义端点就简单地return下一步Entry_No来使用。这应该是 optimistic 意思是你不关心 Entry_No 最终是否真的被使用,但你可以实现终点,这样每次调用都会增加字段在数据库中和 return 下一个值。

Its getting a bit beyond the scope of your initial post, but SQL Server now has support for Sequences that formalise this type of logic from a database and schema point of view, using Sequence simplifies how we can manage these types of incrementations from the client, because we no longer rely on the outcome of data updates to be comitted to the table before the client can increment the next record. (which is what your TOP, Order By Desc solution is trying to do.