Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/linq/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/date/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 转换函数<;t来源,布尔>;Func的谓词<;TDest,bool>;谓语_C#_Linq - Fatal编程技术网

C# 转换函数<;t来源,布尔>;Func的谓词<;TDest,bool>;谓语

C# 转换函数<;t来源,布尔>;Func的谓词<;TDest,bool>;谓语,c#,linq,C#,Linq,我有一个数据层,它通过接受和返回在别处定义的模型来抽象底层实现(实体框架)。我希望能够将Func谓词传递给其中一个方法,以允许在查询数据库时应用附加子句 由于通用模型对底层实体框架实现一无所知,因此我需要将我的Func谓词转换为可以应用于实体框架上下文的谓词 通用模型和实体框架模型具有完全相同的属性名称&我已经有了一个类来执行两者之间的属性值映射。有没有办法将泛型模型委托的目标类型转换为实体框架模型的目标类型 我正在尝试做的一个例子: 给定此委托:func=func 我想将其转换为:dbFunc

我有一个数据层,它通过接受和返回在别处定义的模型来抽象底层实现(实体框架)。我希望能够将
Func
谓词传递给其中一个方法,以允许在查询数据库时应用附加子句

由于通用模型对底层实体框架实现一无所知,因此我需要将我的
Func
谓词转换为可以应用于实体框架上下文的谓词

通用模型和实体框架模型具有完全相同的属性名称&我已经有了一个类来执行两者之间的属性值映射。有没有办法将泛型模型委托的目标类型转换为实体框架模型的目标类型

我正在尝试做的一个例子: 给定此委托:
func=func
我想将其转换为:
dbFunc=Func
并将其应用于上下文:
ctx.Orders.Where(dbDel)

我找到了帖子,但我无法拼凑如何执行转换。整个晚上我都在碰这个,所以任何帮助都将不胜感激

更新

最初的问题和需求似乎有点模糊,所以我将详细介绍我的实现和需求。根据hvd和Alexei的建议,以下代码示例已修改为使用
Expression
&而不是
Func

我有一个接口&一组表示我的数据层的类。它们在数据源上起着伪装的作用,允许不同的实现来访问数据库。我希望能够将其他筛选条件作为谓词传递,并将其应用于底层数据源。但由于façade与底层实现是分开的,因此谓词是使用façade模型类定义的。此外,façade模型类属性与我的实现具有相同的命名,因此可以使用反射直接指定属性

我的外观实施:

namespace Schema.Data
{
    public interface IDataStore
    {
        public IEnumerable<Order> GetOrders(string custCode, Expression<Func<Order, bool>> exp);
    }

    public class Order
    {
        public string CustomerCode { get; set; }
        public string OrderNumber { get; set; }
    }
}
namespace Schema.Data
{
公共接口IDataStore
{
公共IEnumerable GetOrders(字符串custCode,表达式exp);
}
公共阶级秩序
{
公共字符串自定义代码{get;set;}
公共字符串OrderNumber{get;set;}
}
}
然后,我在一个单独的名称空间中实现该接口,使用实体框架查询我的数据库:

namespace Data.EF
{
    // Entity Framework model is in this same namespace

    public class DataStore : Schema.Data.IDataStore
    {
        public IEnumerable<Schema.Data.Order> GetOrders(string custCode, Expression<Func<Schema.Data.Order, bool>> exp)
        {
            using (var ctx = new MyDatabaseEntities()) {
                // TODO: Convert "exp" to Expression<Func<Data.EF.Order, bool>> to pass it in below
                var orders = ctx.Orders.Where(e => e.CustomerCode == custCode).Where(dbExp ?? (n => true));

                // handling the retrieved data & returning result goes here
            }
        }
    }
}
namespace Data.EF
{
//实体框架模型位于同一命名空间中
公共类数据存储:Schema.Data.IDataStore
{
公共IEnumerable GetOrders(字符串custCode,表达式exp)
{
使用(var ctx=new MyDatabaseEntities()){
//TODO:将“exp”转换为表达式以在下面传递它
var orders=ctx.orders.Where(e=>e.CustomerCode==custCode).Where(dbExp??(n=>true));
//处理检索到的数据并返回结果如下
}
}
}
}

如果您只需要将采用一种类型的函数转换为采用另一种类型的函数,请使用常规组合方法-

  TDest MapSourceToDest(TSource v) {....}

  Func<TSource, bool> func = ...;
  Func<TDest, bool> dbFunc = x => func(MapSourceToDest(x));
TDest-MapSourceToDest(TSource v){..}
Func Func=。。。;
Func dbFunc=x=>Func(MapSourceToDest(x));
映射可以通过手工、反射、库或许多其他方法完成


请注意,如果确实需要将此方法传递给EF,则需要
Expression
,而不是
Func
——在这种情况下,实际上可以使用目标类型重写表达式-

Func dbFunc=order=>Func(MapSchemaToModel(order))。。。或者您正在寻找更高级的转换?对于EF,要获得任何有用的东西,您需要一个
表达式,而不是
函数。这是你链接到的帖子中使用的内容,但不是你在这里提问的内容。你想将一种类型转换为另一种你无法(或不愿)访问的类型吗?我觉得很奇怪。@AlexeiLevenkov类似的东西会很好的工作。但我得到一个错误,说明它无法从Models.Order转换为Schema.Data.Order。这发生在传递到MapSchemaToModel的order参数上。我还尝试在Models.Order上添加一个cast操作符,但没有骰子。@hvd我很乐意将façade更改为使用表达式,但在执行转换时也会遇到同样的问题。谢谢您的解释。正如您和hvd所建议的,我将使用表达式,因为这是针对实体框架执行的。现在很晚了,但我明天早上第一件事就是试试这个。非常感谢。@CarlHancke虽然EF希望对表达式进行分析,但EF仍然无法进行分析,因为它不知道如何处理
MapSourceToDest
。您需要自己分析表达式,并自己构建一个不同的表达式。“但这样做并不是微不足道的。”萨华金感谢您的建议,适时地指出。实际上,我在尝试实现我最初的解决方案时遇到了这个问题。正如Alexei提到的,对于EF,我实际上需要表达式,所以我相应地修改了我的外观。对于表达式,转换在EF查询之前完成,因此转换为存储语言的是EF模型表达式,因此MapSourceToDest不是问题。