无法识别实体框架EdmFunction导入
本文关键字:EdmFunction 导入 框架 实体 识别 | 更新日期: 2023-09-27 18:06:05
首先,我之前有一个问题,虽然看起来很相似,但不是同样的问题,看看它:函数从SQL Server导入到实体框架运行时异常
在SQL Server中创建标量函数,然后使用EDM函数映射导入实体框架后,这个函数HammingDistance可以很好地工作。我一直在建设我的网站,在网站和EDMX周围做了一些改变,但没有触及功能并保证它的安全。下面是SQL Server上的SQL函数:
ALTER function [dbo].[HammingDistance]
(@first bigint, @second bigint) returns int
as
begin
declare @xor bigint = @first ^ @second;
declare @one bigint = 1;
declare @diff int = 0;
declare @and bigint;
while (@xor != 0)
begin
set @and = @xor & @one;
if(@and = @one)
begin
set @diff = @diff + 1;
end
set @xor = @xor / 2;
end
return @diff;
end
下面是我的c#代码:
声明:
public static class EdmFunctionMapping
{
[EdmFunction("MainDB.Store", "HammingDistance")]
public static int GetHammingDistance(long hash1, long hash2)
{
throw new NotSupportedException("This method can only be used in a LINQ-to-Entities query");
}
}
用法:
var query = (from p in VisibleObjects.OfType<Photo>()
let hd = EdmFunctionMapping.GetHammingDistance(targetPhoto.Analysis.Hash, p.Analysis.Hash)
let cd = Math.Abs(targetPhoto.Analysis.High.Red - p.Analysis.High.Red)+
Math.Abs(targetPhoto.Analysis.High.Green - p.Analysis.High.Green)+
Math.Abs(targetPhoto.Analysis.High.Blue - p.Analysis.High.Blue) +
Math.Abs(targetPhoto.Analysis.Low.Red - p.Analysis.Low.Red) +
Math.Abs(targetPhoto.Analysis.Low.Green - p.Analysis.Low.Green) +
Math.Abs(targetPhoto.Analysis.Low.Blue - p.Analysis.Low.Blue)
where
hd < 5 ||
(hd < 15 || cd < 100)
orderby hd ascending
select p).Take(50);
return query.ToList();
where VisibleObjects不计算Enumerable。
static IEnumerable<GlobalObject> VisibleObjects
{
get
{
return from obj in db.GlobalObjectSet where obj.IsVisible && !obj.SiteUser.IsDeactivated orderby obj.ID descending select obj;
}
}
一切都是在两三个星期前工作的,在这段时间里,我添加/删除了很多东西,没有检查汉明距离是否有效,所以我不能告诉任何关于它什么时候坏了。它不再工作了,就像EdmFunction属性不存在一样,试图在我的应用程序中进行评估,并抛出我写的异常,说它只能在L2E查询中使用。我已经仔细检查了一切,甚至完全重新创建了数据库,并从EDMX生成,并使用数据库中的更新模型创建和导入函数,它在EDMX中看到函数,并且它可以(显然)在EDMX文件SSDL部分中使用,例如:
<Function Name="HammingDistance" ReturnType="int" Aggregate="false" BuiltIn="false" NiladicFunction="false" IsComposable="true" ParameterTypeSemantics="AllowImplicitConversion" Schema="dbo">
<Parameter Name="first" Type="bigint" Mode="In" />
<Parameter Name="second" Type="bigint" Mode="In" />
</Function>
但是当涉及到应用程序时,它只是不会映射到EDM!尝试了几次,从头开始创建所有数据库,没有任何变化,它在query.ToList()
中抛出异常,并且没有内部异常(这是有意义的,因为它抛出了我自己的异常,不应该由应用程序执行)。我不知道问题的根源,我是不是错过了什么明显的东西?
如果它不能识别Edm映射函数,请确保您没有意外地将查询更改为linq-to-objects,因为这正是您看到该错误的原因。要验证这一点,只需尝试创建另一个测试查询,它将直接访问实体并调用您的函数。比如:
long hash = targetPhoto.Analysis.Hash;
var query = from p in db.GlobalObjectSet.OfType<Photo>()
select new { EdmFunctionMapping.GetHammingDistance(hash, p.Analysis.Hash) };
如果这样的查询通过,你肯定有我提到的问题。
编辑:我想我现在看到问题了。您的
VisibleObjects
返回IEnumerable
=> linq-to-objects。试试这个:
public static IQueryable<GlobalObject> GetVisibleObjects(this IQueryable<GlobalObject> query)
{
return from obj in query
where obj.IsVisible &&
!obj.SiteUser.IsDeactivated
orderby obj.ID descending
select obj;
}
然后像这样调用你的方法:
from p in db.GlobalObjectSet.GetVisibleObjects().OfType<Photo>() ...