Dro*_*iss 5 entity-framework entity-framework-6
我已经使用 Entity Framework 的 Code First 创建了我的数据库模式,其中一个模型有一个复合键(这在 db 中得到了完美的反映)。
但是,当我尝试使用组合键列表查找记录时,我收到一个异常,提示:“无法创建类型为 '匿名类型' 的常量值。此上下文中仅支持原始类型或枚举类型。”
这是我最后使用的失败的代码(它的变体也产生了相同的错误):
var ids = models.Select(m => new { m.Id, m.InstanceId })
.ToArray();
var records = _dataService.TableWithCompositeKey
.Where(t => ids.Contains(new { t.Id, t.InstanceId }))
.ToArray();
Run Code Online (Sandbox Code Playgroud)
评估记录时抛出异常。那么我怎样才能完成这样的任务呢?
编辑:重命名变量,并在多个记录上添加注释,
由于这个问题的性质,我确实假设您希望在另一个记录之后添加单个记录。包含无法在 EF 中执行您想要的操作。
Context.Set<poco>.Find()支持多个字段键
请参阅 Ef 源 public virtual TEntity Find(params object[] keyValues)
var record = _dataService.TableWithCompositeKey
.Find( Id, InstanceId )
.ToList();
Run Code Online (Sandbox Code Playgroud)
如果您无法使用常规 where 子句获取记录并删除不在键列表中的不需要的条目,则:
a) 单独获取 foreach...
find(a,b)
b) 使用类似于 Predicate builder 的东西动态构建 where 子句,请参阅下面,使用 foreach Thischeck = ( a = X and b = Y ) // 例如 create Expression for (Tpoco t)=>value.Equals(t .PropertyName)Whereclause.Or(thisCheck)
观察,如果您要收集的条目数量较少,那么可以考虑个人获得。如果要获取许多记录,则需要考虑生成的Where 子句的大小。这可能最终会对数据库进行全表扫描。
您还需要小心,生成的 Linq 不会导致在找到所需记录之前将所有记录加载到内存中。
这个问题没有好的解决办法。
/// See http://www.albahari.com/expressions for information and examples.
public static class PredicateBuilder
{
public static Expression<Func<T, bool>> True<T> () { return f => true; }
public static Expression<Func<T, bool>> False<T> () { return f => false; }
public static Expression<Func<T, bool>> Or<T> (this Expression<Func<T, bool>> expr1,
Expression<Func<T, bool>> expr2)
{
var invokedExpr = Expression.Invoke (expr2, expr1.Parameters.Cast<Expression> ());
return Expression.Lambda<Func<T, bool>>
(Expression.OrElse (expr1.Body, invokedExpr), expr1.Parameters);
}
public static Expression<Func<T, bool>> And<T> (this Expression<Func<T, bool>> expr1,
Expression<Func<T, bool>> expr2)
{
var invokedExpr = Expression.Invoke (expr2, expr1.Parameters.Cast<Expression> ());
return Expression.Lambda<Func<T, bool>>
(Expression.AndAlso (expr1.Body, invokedExpr), expr1.Parameters);
}
}
Run Code Online (Sandbox Code Playgroud)