private static void SetText(DataContext db, Type tableType, ItemNavigator itemNavigator)
        {
            ParameterExpression param  = Expression.Parameter(tableType, "c");
            Expression          right  = Expression.Constant(itemNavigator.ValueNullable.Value);
            Expression          left   = Expression.Property(param, tableType.GetProperty("id"));
            Expression          filter = Expression.Equal(left, right);
            Expression          pred   = Expression.Lambda(filter, param);

            ITable     table = db.GetTable(tableType);
            Expression expr  = Expression.Call(typeof(Queryable), "Where", new[] { tableType },
                                               Expression.Constant(table), pred);
            IQueryable  query      = table.AsQueryable().Provider.CreateQuery(expr);
            IEnumerator enumerator = query.GetEnumerator();

            if (!enumerator.MoveNext())
            {
                itemNavigator.Text = "[запись не найдена]";
                return;
            }
            var obj = enumerator.Current;

            itemNavigator.Text = GetText(obj, itemNavigator.ColumnName);
            if (!string.IsNullOrEmpty(itemNavigator.AlternativeColumnName))
            {
                itemNavigator.AlternativeText = GetText(obj, itemNavigator.AlternativeColumnName);
            }
        }
        public void LINQ_orderby_int()
        {
            var q = from r in table.AsQueryable()
                    orderby r.IntProp
                    select r;

            var l = q.ToList();

            Assert.AreEqual(2, l.Count);
            Assert.AreEqual(e1.IntProp, l[0].IntProp);
            Assert.AreEqual(e2.IntProp, l[1].IntProp);
        }
        public static IUpdatable <JoinHelper <T, T> > BuildBulkUpdate <T>(
            DataConnection dataConnection,
            ITable <T> target,
            ITable <T> sourceTable,
            params Expression <Func <T, object> >[] fields
            ) where T : class
        {
            var descriptor = dataConnection.MappingSchema.GetEntityDescriptor(typeof(T));
            var members    = new List <MemberInfo>();

            if (fields.Length == 0)
            {
                members.AddRange(
                    descriptor.Columns
                    .Where(c => !c.SkipOnUpdate & !c.IsPrimaryKey & !c.IsIdentity)
                    .Select(c => c.MemberInfo)
                    );
            }
            else
            {
                foreach (var field in fields)
                {
                    var member = MemberHelper.GetMemberInfo(field);
                    if (member == null)
                    {
                        throw new LinqToDBException($"Can not retrive member info from lambda function: {field}");
                    }
                    members.Add(member);
                }
            }

            /* Emulating the following calls
             *
             *      var join = target.InnerJoin(temporaryTable, (outer, inner) => outer.ID1 == inner.ID1 && outer.ID2 == inner.ID2,
             *              (outer, inner) => new DynamicExtensions.JoinHelper<BulkUpdateEntity, BulkUpdateEntity>
             *              {
             *                      Outer = outer,
             *                      Inner = inner
             *              });
             *
             *      var updatable = join.AsUpdatable();
             *      updatable = updatable.Set(pair => pair.Outer.Value1, pair => pair.Inner.Value1);
             *      updatable = updatable.Set(pair => pair.Outer.Value2, pair => pair.Inner.Value2);
             */

            var joinMethod = InnerJoinMethodInfo.MakeGenericMethod(typeof(T), typeof(T), typeof(JoinHelper <T, T>));

            var outerParam = Expression.Parameter(typeof(T), "outer");
            var innerParam = Expression.Parameter(typeof(T), "inner");

            Expression cmpExpression = null;

            foreach (var c in descriptor.Columns.Where(c => c.IsPrimaryKey))
            {
                var equals = Expression.Equal(
                    Expression.MakeMemberAccess(outerParam, c.MemberInfo),
                    Expression.MakeMemberAccess(innerParam, c.MemberInfo)
                    );
                cmpExpression = cmpExpression == null ? equals : Expression.AndAlso(cmpExpression, equals);
            }

            if (cmpExpression == null)
            {
                throw new LinqToDBException($"Entity {typeof(T)} does not contain primary key");
            }

            var equalityLambda = Expression.Lambda(cmpExpression, outerParam, innerParam);

            var helperType  = typeof(JoinHelper <T, T>);
            var constructor = helperType.GetConstructor(new Type[0]);

            var joinHelperOuterPropertyInfo = helperType.GetProperty("Outer");
            var joinHelperInnerPropertyInfo = helperType.GetProperty("Inner");

            var newExpression =
                Expression.Lambda(
                    Expression.MemberInit(
                        Expression.New(constructor),
                        Expression.Bind(joinHelperOuterPropertyInfo, outerParam),
                        Expression.Bind(joinHelperInnerPropertyInfo, innerParam)
                        ),
                    outerParam,
                    innerParam);

            var    joinQuery = joinMethod.Invoke(null, new object[] { target.AsQueryable(), sourceTable.AsQueryable(), equalityLambda, newExpression });
            object updatable = ((IQueryable <JoinHelper <T, T> >)joinQuery).AsUpdatable();

            var helperParam     = Expression.Parameter(helperType, "pair");
            var outerExpression = Expression.MakeMemberAccess(helperParam, joinHelperOuterPropertyInfo);
            var innerExpression = Expression.MakeMemberAccess(helperParam, joinHelperInnerPropertyInfo);

            foreach (var memberInfo in members)
            {
                var method = SetExpressionMethodInfo.MakeGenericMethod(helperType, memberInfo.GetMemberType());

                var propLambda  = Expression.Lambda(Expression.MakeMemberAccess(outerExpression, memberInfo), helperParam);
                var valueLambda = Expression.Lambda(Expression.MakeMemberAccess(innerExpression, memberInfo), helperParam);

                updatable = method.Invoke(null, new object[] { updatable, propLambda, valueLambda });
            }

            return((IUpdatable <JoinHelper <T, T> >)updatable);
        }