国产探花免费观看_亚洲丰满少妇自慰呻吟_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)就可以了。

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

 


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 旬邑县| 江北区| 宁波市| 锡林郭勒盟| 扎赉特旗| 都安| 泗水县| 兰州市| 宜春市| 新闻| 金华市| 金乡县| 台北县| 西盟| 浙江省| 灵武市| 大足县| 郸城县| 灵宝市| 缙云县| 容城县| 鹤山市| 财经| 沧州市| 建瓯市| 潼关县| 延川县| 浦东新区| 昌平区| 峨山| 鸡西市| 汾西县| 博兴县| 保康县| 巴彦淖尔市| 泌阳县| 老河口市| 岳西县| 芜湖市| 兴山县| 鄢陵县|