2

鉴于:

class MyDao
{
   public int SiteId {get;set;}

   public Cv3AddressDao ReadSingle(Expression<Func<Cv3AddressDao, bool>> predicate)
   { //...
   }
}

class MyEntity
{
   public int SiteId {get;set;}
}

如何获取类型的谓词参数Expression<Func<MyDao, bool>>并将其转换为Expression<Func<MyEntity, bool>>

我正在寻找的答案类型

请注意,答案必须显示转换是如何工作的。我想要一个与此类似但有效的实现:)....

    public MyDao ReadSingle(Expression<Func<MyDao , bool>> predicate)
    {
        var mappedPredicate = MapFun<MyDao , MyEntity>(predicate);
        var result = repository.GetSingle<MyEntity>(mappedPredicate);

        return Convert(result);//Converts Entity to Dao...safe to ignore this line
    }

    Expression<Func<B, bool>> MapFun<A, B>(Expression<Func<A, bool>> input)
    {
        Expression<Func<B, bool>> result = null;//How to convert?
        return result;
    }

关于我为什么想要这个设计的详细信息......

这是一个 asp.net MVC 5 应用程序。这种转换很重要的原因是我的 View 不知道类型MyEntity。换句话说,如果我要这样做:

myDaoObject.ReadSingle<MyEntity>(myEntity => myEntity.SiteId == "123");

然后我的视图层必须引用我的 DLL 层,因为我在这里使用MyEntity. 我希望 View 层与 Dao 一起工作:

myDaoObject.ReadSingle<MyDao>(myDao=> myDao.SiteId == "123");

但是,现在我必须转换 Dao 以使其可用于存储库。Repository 只知道 DL 对象。我试图避免创建冗余存储库只是为了支持这种翻译。DAO 包含实体的所有属性以及一些属性。

4

4 回答 4

3

我手头没有确切的代码,但您可能希望使用提供的表达式并自己执行等价转换。

这个stackoverflow问题与我会做的事情一致。

P.Brian.Mackey 的说明

提到的答案有效。使用乔恩的答案就可以了。然而,答案的公开部分最终成为了一个不可见的Func<>转换参与者。我只需要:

    Expression<Func<B, bool>> MapFun<A, B>(Expression<Func<A, bool>> input)where A : class
    {
        var result = DbAccessLayer.TransformPredicateLambda<A,B>(input);
        return result;
    }

请注意,此方法是私有的。我把它改成了公开的。有关完整实施,请参阅上面引用的答案中的@Jon 答案。

public static Expression<Func<TNewTarget, bool>> TransformPredicateLambda<TOldTarget, TNewTarget>(Expression<Func<TOldTarget, bool>> predicate)
于 2013-08-16T16:20:37.360 回答
1

让他们共享一个通用接口:

public interface ISited {
    int SiteId {get; set; }
}

class MyDao : ISited { .. }
class MyEntity : ISited { .. }

并使用通用接口作为泛型类型参数的约束来代替C3VAddressDao

 public ISited ReadSingle(Expression<Func<ISited, bool>> predicate)

当然,如果没有您将包含在ISited.

于 2013-08-16T14:46:35.783 回答
0

为什么不传进去

public Cv3AddressDao ReadSingle<TEntity>(Expression<Func<TEntity, bool>> predicate)
{
    // ...
}
...
var dao = new MyDao();
var addr = dao.ReadSingle<MyEntity>(x => x.SiteId == 1);
于 2013-08-16T14:44:08.627 回答
0
    public static Expression<Func<B, bool>> MapFun<A, B>(Expression<Func<A, bool>> input) where A : class
    {
        return b => input.Compile()((b as A));
    }

这应该对你有用,因为你只是在转换参数。

更新:

根据您更新的答案,您有几个选择。

使用反射将值从实体复制到 DAO(查看类似AutoMapper的内容)

您拥有的另一个选项是使用 IConvertable 之类的东西定义您的 2 种类型之间的自定义转换。

于 2013-08-16T15:26:23.047 回答