3

有没有办法为 Linq2Entities 的附加功能定义 SQL 转换组件。

例如:

myQuery.Where(entity => entity.Contains('foo', SearchFlags.All))

理想情况下,我正在寻找不需要直接编辑和构建新版本 EntityFramework.dll 的东西。有没有办法允许扩展方法到可以支持 SQL 生成的实体框架。

到目前为止,我有一个模板可以代表我需要为 LINQ to Entities 替换的方法:

public static bool Contains(this object source, string searchTerms, SearchFlags flags)
{
    return true;
}

当然这会导致错误:

LINQ to Entities 无法识别方法 'Boolean CONTAINS(System.Object, System.String, SearchFlags)' 方法,并且此方法无法转换为存储表达式。

明确地说,我不想这样做:

myQuery.AsEnumerable().Where(entity => entity.Contains('foo', SearchFlags.All))

因为我希望能够在 SQL 空间中执行代码,而不是手动返回所有实体。

我也不能使用.ToString()ofIQueryable并手动执行它,因为我需要 Entity Framework 来填充来自多个.Include连接的对象。

4

2 回答 2

0

我不太清楚你的Q。但是,如果您的问题是您不能使用自己的方法或其他 linq to objects 方法,只需.AsEnumerable()通过 linq to objects 使用和完成您的其他工作,而不是 L2E:

myQuery.AsEnumerable().Where(entity => entity.Contains('foo', SearchFlags.All))

如果您需要在myQuery其他地方多次使用,请先将其加载到内存中,然后根据需要使用它:

var myQuery = from e in context.myEntities
              select d;
myQuery.Load();

// ...

var myOtherQuery = from d in context.myEntities.Local                        
                    select d;
                    // Now any L2O method is supported...
于 2013-07-31T19:26:55.860 回答
0

我最终做了以下事情(这有效,但远非完美):

  1. 我所有的实体都继承自IEntitywhich 定义long Id { get; set; }
  2. 然后我添加了一个冗余限制 context.myEntities.Where(entity => entity.Id != 0),这是多余的,因为标识从 1 开始,但 Linq2Entities 不知道这一点。
  3. .ToString()然后我在IQueryable完成所有其他查询后调用它,因为它是DBQuery<Entity>返回 SQL 命令文本的类型,所以我用我的查询限制进行了简单的替换。
  4. 为了让所有.Include(...)工作正常,我实际上执行了两个不同的 sql 命令。没有其他更漂亮的方法可以利用这一点,因为查询执行计划缓存会导致问题(即使禁用)。

结果我的代码如下所示:

public IQueryable<IEntity> MyNewFunction(IQueryable<IEntity> myQueryable, string queryRestriction)
{
    string rawSQL = myQueryable.Select(entity => entity.Id).ToString().Replace("[Extent1].Id <> 0", queryRestriction);
    List<long> ids = // now execute rawSQL, get the list of ids;
    return myQuerable.Where(entity => ids.Contains(entity.Id));
}

简而言之,除了手动执行 SQL 或运行类似的 SQL 命令并使用现有命令附加限制之外,将您自己的方法写入 Linq-to-Entities 的唯一方法是手动更改和构建您自己的 EntityFramework.dll 从EF6 源。

于 2013-08-01T06:50:34.260 回答