国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

C#ORM中DtoLinqExpression和數據庫ModelLinqExpression之間的轉換

2019-11-14 14:02:03
字體:
來源:轉載
供稿:網友

今天在百度知道中看到一個問題,研究了一會便回答了:

http://zhidao.baidu.com/question/920461189016484459.html

如何使dto linq 表達式轉換到數據庫實體對象linq表達式。自己搜集了一些資料然后實戰了一下,還是可行。

自己擴展的一個方法 Cast<TInput, TToPRoperty>(this Expression<Func<TInput, bool>> expression),代碼如下:

namespace System{    public static class LambdaExpressionExtensions    {        private static Expression Parser(ParameterExpression parameter, Expression expression)        {            if (expression == null) return null;            switch (expression.NodeType)            {                //一元運算符                case ExpressionType.Negate:                case ExpressionType.NegateChecked:                case ExpressionType.Not:                case ExpressionType.Convert:                case ExpressionType.ConvertChecked:                case ExpressionType.ArrayLength:                case ExpressionType.Quote:                case ExpressionType.TypeAs:                    {                        var unary = expression as UnaryExpression;                        var exp = Parser(parameter, unary.Operand);                        return Expression.MakeUnary(expression.NodeType, exp, unary.Type, unary.Method);                    }                //二元運算符                case ExpressionType.Add:                case ExpressionType.AddChecked:                case ExpressionType.Subtract:                case ExpressionType.SubtractChecked:                case ExpressionType.Multiply:                case ExpressionType.MultiplyChecked:                case ExpressionType.Divide:                case ExpressionType.Modulo:                case ExpressionType.And:                case ExpressionType.AndAlso:                case ExpressionType.Or:                case ExpressionType.OrElse:                case ExpressionType.LessThan:                case ExpressionType.LessThanOrEqual:                case ExpressionType.GreaterThan:                case ExpressionType.GreaterThanOrEqual:                case ExpressionType.Equal:                case ExpressionType.NotEqual:                case ExpressionType.Coalesce:                case ExpressionType.ArrayIndex:                case ExpressionType.RightShift:                case ExpressionType.LeftShift:                case ExpressionType.ExclusiveOr:                    {                        var binary = expression as BinaryExpression;                        var left = Parser(parameter, binary.Left);                        var right = Parser(parameter, binary.Right);                        var conversion = Parser(parameter, binary.Conversion);                        if (binary.NodeType == ExpressionType.Coalesce && binary.Conversion != null)                        {                            return Expression.Coalesce(left, right, conversion as LambdaExpression);                        }                        else                        {                            return Expression.MakeBinary(expression.NodeType, left, right, binary.IsLiftedToNull, binary.Method);                        }                    }                //其他                case ExpressionType.Call:                    {                        var call = expression as MethodCallExpression;                        List<Expression> arguments = new List<Expression>();                        foreach (var argument in call.Arguments)                        {                            arguments.Add(Parser(parameter, argument));                        }                        var instance = Parser(parameter, call.Object);                        call = Expression.Call(instance, call.Method, arguments);                        return call;                    }                case ExpressionType.Lambda:                    {                        var Lambda = expression as LambdaExpression;                        return Parser(parameter, Lambda.Body);                    }                case ExpressionType.Memberaccess:                    {                        var memberAccess = expression as MemberExpression;                        if (memberAccess.Expression == null)                        {                            memberAccess = Expression.MakeMemberAccess(null, memberAccess.Member);                        }                        else                        {                            var exp = Parser(parameter, memberAccess.Expression);                            var member = exp.Type.GetMember(memberAccess.Member.Name).FirstOrDefault();                            memberAccess = Expression.MakeMemberAccess(exp, member);                        }                        return memberAccess;                    }                case ExpressionType.Parameter:                    return parameter;                case ExpressionType.Constant:                    return expression;                case ExpressionType.TypeIs:                    {                        var typeis = expression as TypeBinaryExpression;                        var exp = Parser(parameter, typeis.Expression);                        return Expression.TypeIs(exp, typeis.TypeOperand);                    }                default:                    throw new Exception(string.Format("Unhandled expression type: '{0}'", expression.NodeType));            }        }        public static Expression<Func<TToProperty, bool>> Cast<TInput, TToProperty>(this Expression<Func<TInput, bool>> expression)        {            var p = Expression.Parameter(typeof(TToProperty), "p");            var x = Parser(p, expression);            return Expression.Lambda<Func<TToProperty, bool>>(x, p);        }    }}

比如有如下的 實體類對象:

    public class User    {        public int Id { get; set; }        public string Name { get; set; }    }    public class UserDto    {        public int Id { get; set; }        public string Name { get; set; }    }

簡單的測試代碼:

    class Program    {        static int[] array0 = new[] { 0, 1 };        static void Main1(string[] args)        {            var array1 = new[] { 0, 1 };            Expression<Func<UserDto, bool>> exp = null;            Expression<Func<User, bool>> exp2 = null;            //====exp====            //exp = u => u.Name == "張三";            //exp = u => u.Id.Equals(1);            //exp = u => u.Id.Equals(1) && u.Name == "張三";            //exp = u => u.Id.Equals(1) && u.Name == "張三" || u.Name == "張三";            //exp = u => Filter(u.Name);            //exp = u => !Filter(u.Name);            //exp = u => u.Id.Equals(1) && u.Name == "張三" && Filter(u.Name);            //exp = u => array1.Contains(u.Id);            //exp = u => array1.Contains(u.Id) || u.Name == "張三";            //exp = u => array0.Contains(u.Id);            //exp = u => u.Id > 0;            //exp = u => u.Id < 10;            //exp = u => u.Id * 2 < 10;            //exp = u => u.Id - 2 < 10;            //exp = u => u.Id + 2 < 10;            //exp = u => u.Id / 2 < 10;            //exp = u => (int)(u.Id / 2) < 10;            //exp = u => u.Name is string;            //exp = u => ((object)u.Id).ToString() == "1";            //exp = u => u.Id == default(int);            //exp = u => true;            //exp = u => Math.Abs(u.Id)==1;            exp = u =>                        u.Id.Equals(1)                        && u.Name == "張三"                        && u.Id < 10                        && array1.Contains(u.Id)                        && u.Id + 2 < 10                        && (((object)u.Id).ToString() == "1" || u.Name.Contains(""))                        && Math.Abs(u.Id) == 1                        && Filter(u.Name)                        && true                        ;            //=====exp2=====            exp2 = exp.Cast<UserDto, User>();            Console.WriteLine(exp.ToString());            Console.WriteLine(exp.ToString());            //測試數據            List<User> list = new List<User>() {                 new User{ Id=0,Name="AAA"},                new User{ Id=1,Name="張三"},                new User{ Id=2,Name="李四"}            };            var item = list.Where(exp2.Compile()).FirstOrDefault();            Console.WriteLine(item.Name);            Console.ReadKey();        }        public static bool Filter(string name)        {            return name.Contains("");        }    }

應該說常用的篩選條件都是支持的。這里的list由于沒有數據庫環境就用List<User>模擬的,真實ORM環境換成list.Where(exp2)就可以了。

性能方面沒有測試,應該是可以使用緩存的。有興趣的朋友可以改一下。

 


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 抚宁县| 化州市| 兴海县| 平度市| 开江县| 铜鼓县| 清流县| 神木县| 米易县| 葫芦岛市| 沾益县| 吕梁市| 葫芦岛市| 枣强县| 建湖县| 曲阜市| 黎平县| 峨眉山市| 丹凤县| 陆丰市| 漳平市| 奉贤区| 台南县| 安庆市| 洪泽县| 霍邱县| 雅江县| 平乐县| 宜宾县| 宁蒗| 阿城市| 四会市| 苍梧县| 浮梁县| 大石桥市| 稷山县| 宁波市| 汤阴县| 廊坊市| 莱西市| 顺义区|