gpt4 book ai didi

c# - 使用 Linq to Entities 读取 byte[] 或 float

转载 作者:行者123 更新时间:2023-12-03 20:12:12 25 4
gpt4 key购买 nike

我有一个表,其中一列是二进制的,另一列是 float 的。我需要使用 SQL 选择以下内容

SELECT ISNULL(myBinary, myFloat) FROM table

这行得通,我得到了一个包含所有二进制文件的列

0x3F800000
0xE5C13DBAB611123B47A7
0x9946C3BA9946C3BA9946
0xDE0E1D3C8B7A143C6DB7
0x3F800000

等等

现在我想使用 Linq to Entities 进行此查询,但是我找不到可以编译的代码

context.table.select(s => new MyObject()
{
Result = s.myBinary ?? s.myFloat // <--- '??' operator cannot be applied to operands of type 'byte[]' and 'float'
});

class MyObject { public Object Result {get; set;} }

我如何获得这些值? BitConverter 也不起作用( float )

更新

为什么我要问:所以如果我要分别选择两列,我会得到更多的执行时间

set statistics time on
SELECT TOP (5000) ISNULL([x], [y])
FROM [table];
set statistics time off
set statistics time on
SELECT TOP (5000) [x], [y]
FROM [table];
set statistics time off

yields(即使执行多次,也总是差不多)

(5000 rows affected)

SQL Server Execution Times:
CPU time = 0 ms, elapsed time = 7 ms.

(5000 rows affected)

SQL Server Execution Times:
CPU time = 0 ms, elapsed time = 113 ms.

注意:在一条评论中,我写了因子 40,那是用另一种测量方法。统计时间 yield 约为 10 倍。

如果我增加行数,我得到

(50000 rows affected)

SQL Server Execution Times:
CPU time = 47 ms, elapsed time = 820 ms. (with ISNULL)

(50000 rows affected)

SQL Server Execution Times:
CPU time = 16 ms, elapsed time = 1365 ms.

如果行数较少(大约 1000 或更少),则执行时间无法同等测量,因此约为 1 毫秒。但是:我预计每个查询大约有 5000 到 10000 行。

最佳答案

我可以提供的解决方案是自定义存储功能,映射到内置 ISNULL SQL函数。

如果您使用的是 Code First 模型,则需要 EntityFramework.Functions包。

但是由于你使用的是edmx,这个过程有点复杂,需要手动编辑edmx文件。 How to: Define Custom Functions in the Storage Model 部分涵盖了该技术MSDN 主题。

使用 XML(文本)编辑器打开您的 edmx 文件。找到 Schema edmx:StorageModels 的子元素元素并在里面添加以下内容:

<Function Name="IsNull" BuiltIn="true" IsComposable="true" ReturnType="binary">
<Parameter Name="expr1" Type="binary" />
<Parameter Name="expr2" Type="float" />
</Function>

请注意,如 MSDN 链接中所述:

Changes made to the SSDL section of an .edmx file, as suggested in the procedure below, will be overwritten if you use the Update Model Wizard to update your model.

所以请确保将其保存在安全的地方,如果您从数据库更新 edmx,请重新包含它。

然后在一些静态类中添加一个方法并用DbFunction 装饰它属性:

public static class CustomDbFunctions
{
const string Namespace = "EFTest.MyDbContextModel.Store";

[DbFunction(Namespace, "IsNull")]
public static byte[] IsNull(byte[] expr1, double expr2) => throw new NotSupportedException();
}

(更新 Namespace 字符串以匹配 Namespace 元素的 <edmx:StorageModels><Schema> 属性的值)。

仅此而已。现在您应该能够在 LINQ to Entities 查询中使用上述函数:

class MyObject { public byte[] Result { get; set;} }

context.MyTable.Select(e => new MyObject
{
Result = CustomDbFunctions.IsNull(e.myBinary, e.myFloat)
});

EF6 会很乐意将其转换为所需的 SQL ISNULL功能。

关于c# - 使用 Linq to Entities 读取 byte[] 或 float,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50986217/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com