예제 #1
0
        public override EntityExpression GetEntityExpression(Expression root, MappingEntity entity)
        {
            // must be some complex type constructed from multiple columns
            var assignments = new List<EntityAssignment>();
            foreach (MemberInfo mi in this.mapping.GetMappedMembers(entity))
            {
                if (!this.mapping.IsAssociationRelationship(entity, mi))
                {
                    Expression me;
                    if (this.mapping.IsNestedEntity(entity, mi))
                    {
                        me = this.GetEntityExpression(root, this.mapping.GetRelatedEntity(entity, mi));
                    }
                    else
                    {
                        me = this.GetMemberExpression(root, entity, mi);
                    }
                    if (me != null)
                    {
                        assignments.Add(new EntityAssignment(mi, me));
                    }
                }
            }

            return new EntityExpression(entity, this.BuildEntityExpression(entity, assignments));
        }
예제 #2
0
        public override Expression GetDeleteExpression(MappingEntity entity, Expression instance, LambdaExpression deleteCheck)
        {
            var tables = this.mapping.GetTables(entity);
            if (tables.Count < 2)
            {
                return base.GetDeleteExpression(entity, instance, deleteCheck);
            }

            var commands = new List<Expression>();
            foreach (var table in this.GetDependencyOrderedTables(entity).Reverse())
            {
                TableExpression tex = new TableExpression(new TableAlias(), entity, this.mapping.GetTableName(table));
                var where = this.GetIdentityCheck(tex, entity, instance);
                commands.Add(new DeleteCommand(tex, where));
            }

            Expression block = new BlockCommand(commands);

            if (deleteCheck != null)
            {
                var test = this.GetEntityStateTest(entity, instance, deleteCheck);
                return new IFCommand(test, block, null);
            }

            return block;
        }
예제 #3
0
 /// <summary>
 /// The query language specific type for the column
 /// </summary>
 /// <param name="member"></param>
 /// <returns></returns>
 public virtual QueryType GetColumnType(MappingEntity entity, MemberInfo member)
 {
     string dbType = this.mapping.GetColumnDbType(entity, member);
     if (dbType != null)
     {
         return this.translator.Linguist.Language.TypeSystem.Parse(dbType);
     }
     return this.translator.Linguist.Language.TypeSystem.GetColumnType(TypeHelper.GetMemberType(member));
 }
예제 #4
0
        public override Expression GetDeleteExpression(MappingEntity entity, Expression instance, LambdaExpression deleteCheck)
        {
            TableExpression table = new TableExpression(new TableAlias(), entity, this.mapping.GetTableName(entity));
            Expression where = null;

            if (instance != null)
            {
                where = this.GetIdentityCheck(table, entity, instance);
            }

            if (deleteCheck != null)
            {
                Expression row = this.GetEntityExpression(table, entity);
                Expression pred = DbExpressionReplacer.Replace(deleteCheck.Body, deleteCheck.Parameters[0], row);
                where = (where != null) ? where.And(pred) : pred;
            }

            return new DeleteCommand(table, where);
        }
예제 #5
0
 /// <summary>
 /// The name of the corresponding database table
 /// </summary>
 /// <param name="rowType"></param>
 /// <returns></returns>
 public virtual string GetTableName(MappingEntity entity)
 {
     return entity.EntityType.Name;
 }
예제 #6
0
        public override Expression GetPrimaryKeyQuery(MappingEntity entity, Expression source, Expression[] keys)
        {
            // make predicate
            ParameterExpression p = Expression.Parameter(entity.ElementType, "p");
            Expression pred = null;
            var idMembers = this.GetPrimaryKeyMembers(entity).ToList();
            if (idMembers.Count != keys.Length)
            {
                throw new InvalidOperationException("Incorrect number of primary key values");
            }
            for (int i = 0, n = keys.Length; i < n; i++)
            {
                MemberInfo mem = idMembers[i];
                Type memberType = TypeHelper.GetMemberType(mem);
                if (keys[i] != null && TypeHelper.GetNonNullableType(keys[i].Type) != TypeHelper.GetNonNullableType(memberType))
                {
                    throw new InvalidOperationException("Primary key value is wrong type");
                }
                Expression eq = Expression.MakeMemberAccess(p, mem).Equal(keys[i]);
                pred = (pred == null) ? eq : pred.And(eq);
            }
            var predLambda = Expression.Lambda(pred, p);

            return Expression.Call(typeof(Queryable), "SingleOrDefault", new Type[] { entity.ElementType }, source, predLambda);
        }
예제 #7
0
 /// <summary>
 /// The type of the entity on the other side of the relationship
 /// </summary>
 /// <param name="member"></param>
 /// <returns></returns>
 public virtual MappingEntity GetRelatedEntity(MappingEntity entity, MemberInfo member)
 {
     Type relatedType = TypeHelper.GetElementType(TypeHelper.GetMemberType(member));
     return this.GetEntity(relatedType);
 }
예제 #8
0
 protected virtual Expression GetUpdateResult(MappingEntity entity, Expression instance, LambdaExpression selector)
 {
     var tq = this.GetQueryExpression(entity);
     Expression where = this.GetIdentityCheck(tq.Select, entity, instance);
     Expression selection = DbExpressionReplacer.Replace(selector.Body, selector.Parameters[0], tq.Projector);
     TableAlias newAlias = new TableAlias();
     var pc = ColumnProjector.ProjectColumns(this.translator.Linguist.Language, selection, null, newAlias, tq.Select.Alias);
     return new ProjectionExpression(
         new SelectExpression(newAlias, pc.Columns, tq.Select, where),
         pc.Projector,
         Aggregator.GetAggregator(selector.Body.Type, typeof(IEnumerable<>).MakeGenericType(selector.Body.Type))
         );
 }
예제 #9
0
 public override object GetPrimaryKey(MappingEntity entity, object instance)
 {
     object firstKey = null;
     List<object> keys = null;
     foreach (var mi in this.GetPrimaryKeyMembers(entity))
     {
         if (firstKey == null)
         {
             firstKey = mi.GetValue(instance);
         }
         else
         {
             if (keys == null)
             {
                 keys = new List<object>();
                 keys.Add(firstKey);
             }
             keys.Add(mi.GetValue(instance));
         }
     }
     if (keys != null)
     {
         return new CompoundKey(keys.ToArray());
     }
     return firstKey;
 }
예제 #10
0
 /// <summary>
 /// Determines if a property is generated on the server during insert
 /// </summary>
 /// <param name="member"></param>
 /// <returns></returns>
 public virtual bool IsGenerated(MappingEntity entity, MemberInfo member)
 {
     return false;
 }
예제 #11
0
 public override bool IsModified(MappingEntity entity, object instance, object original)
 {
     foreach (var mi in this.GetMappedMembers(entity))
     {
         if (this.IsColumn(entity, mi))
         {
             if (!object.Equals(mi.GetValue(instance), mi.GetValue(original)))
                 return true;
         }
     }
     return false;
 }
예제 #12
0
 /// <summary>
 /// The type declaration for the column in the provider's syntax
 /// </summary>
 /// <param name="entity"></param>
 /// <param name="member"></param>
 /// <returns>a string representing the type declaration or null</returns>
 public virtual string GetColumnDbType(MappingEntity entity, MemberInfo member)
 {
     return null;
 }
예제 #13
0
 /// <summary>
 /// The name of the corresponding table column
 /// </summary>
 /// <param name="member"></param>
 /// <returns></returns>
 public virtual string GetColumnName(MappingEntity entity, MemberInfo member)
 {
     return member.Name;
 }
예제 #14
0
 public override object CloneEntity(MappingEntity entity, object instance)
 {
     var clone = System.Runtime.Serialization.FormatterServices.GetUninitializedObject(entity.EntityType);
     foreach (var mi in this.GetMappedMembers(entity))
     {
         if (this.IsColumn(entity, mi))
         {
             mi.SetValue(clone, mi.GetValue(instance));
         }
     }
     return clone;
 }
예제 #15
0
 /// <summary>
 /// Returns the key members on the other side (related side) of the association
 /// </summary>
 /// <param name="entity"></param>
 /// <param name="member"></param>
 /// <returns></returns>
 public virtual IEnumerable<MemberInfo> GetAssociationRelatedKeyMembers(MappingEntity entity, MemberInfo member)
 {
     return new MemberInfo[] { };
 }
예제 #16
0
 protected virtual Expression GetIdentityCheck(Expression root, MappingEntity entity, Expression instance)
 {
     return this.mapping.GetMappedMembers(entity)
     .Where(m => this.mapping.IsPrimaryKey(entity, m))
     .Select(m => this.GetMemberExpression(root, entity, m).Equal(Expression.MakeMemberAccess(instance, m)))
     .Aggregate((x, y) => x.And(y));
 }
예제 #17
0
 private bool IsNullRelationshipAssignment(MappingEntity entity, EntityAssignment assignment)
 {
     if (this.mapping.IsRelationship(entity, assignment.Member))
     {
         var cex = assignment.Expression as ConstantExpression;
         if (cex != null && cex.Value == null)
             return true;
     }
     return false;
 }
예제 #18
0
 private IEnumerable<ColumnAssignment> GetColumnAssignments(Expression table, Expression instance, MappingEntity entity, Func<MappingEntity, MemberInfo, bool> fnIncludeColumn)
 {
     foreach (var m in this.mapping.GetMappedMembers(entity))
     {
         if (this.mapping.IsColumn(entity, m) && fnIncludeColumn(entity, m))
         {
             yield return new ColumnAssignment(
                 (ColumnExpression)this.GetMemberExpression(table, entity, m),
                 Expression.MakeMemberAccess(instance, m)
                 );
         }
     }
 }
예제 #19
0
 /// <summary>
 /// Determines if the property is an assocation relationship.
 /// </summary>
 /// <param name="entity"></param>
 /// <param name="member"></param>
 /// <returns></returns>
 public virtual bool IsAssociationRelationship(MappingEntity entity, MemberInfo member)
 {
     return false;
 }
예제 #20
0
 public override bool IsRelationship(MappingEntity entity, MemberInfo member)
 {
     return this.IsAssociationRelationship(entity, member);
 }
예제 #21
0
 /// <summary>
 /// Determines if a property is mapped onto a column
 /// </summary>
 /// <param name="member"></param>
 /// <returns></returns>
 public virtual bool IsColumn(MappingEntity entity, MemberInfo member)
 {
     //return this.mapping.IsMapped(entity, member) && this.translator.Linguist.Language.IsScalar(TypeHelper.GetMemberType(member));
     return this.IsMapped(entity, member);
 }
예제 #22
0
 public abstract bool IsRelationshipTarget(MappingEntity entity, MemberInfo member);
예제 #23
0
 /// <summary>
 /// Deterimines is a property is mapped onto a column or relationship
 /// </summary>
 /// <param name="member"></param>
 /// <returns></returns>
 public virtual bool IsMapped(MappingEntity entity, MemberInfo member)
 {
     return true;
 }
예제 #24
0
 protected virtual DeclarationCommand GetGeneratedIdCommand(MappingEntity entity, List<MemberInfo> members, Dictionary<MemberInfo, Expression> map)
 {
     var columns = new List<ColumnDeclaration>();
     var decls = new List<VariableDeclaration>();
     var alias = new TableAlias();
     foreach (var member in members)
     {
         Expression genId = this.translator.Linguist.Language.GetGeneratedIdExpression(member);
         var name = member.Name;
         var colType = this.GetColumnType(entity, member);
         columns.Add(new ColumnDeclaration(member.Name, genId, colType));
         decls.Add(new VariableDeclaration(member.Name, colType, new ColumnExpression(genId.Type, colType, alias, member.Name)));
         if (map != null)
         {
             var vex = new VariableExpression(member.Name, TypeHelper.GetMemberType(member), colType);
             map.Add(member, vex);
         }
     }
     var select = new SelectExpression(alias, columns, null, null);
     return new DeclarationCommand(decls, select);
 }
예제 #25
0
 /// <summary>
 /// Determines if a property represents or is part of the entities unique identity (often primary key)
 /// </summary>
 /// <param name="member"></param>
 /// <returns></returns>
 public override bool IsPrimaryKey(MappingEntity entity, MemberInfo member)
 {
     return false;
 }
예제 #26
0
        protected virtual Expression GetInsertResult(MappingEntity entity, Expression instance, LambdaExpression selector, Dictionary<MemberInfo, Expression> map)
        {
            var tableAlias = new TableAlias();
            var tex = new TableExpression(tableAlias, entity, this.mapping.GetTableName(entity));
            var aggregator = Aggregator.GetAggregator(selector.Body.Type, typeof(IEnumerable<>).MakeGenericType(selector.Body.Type));

            Expression where;
            DeclarationCommand genIdCommand = null;
            var generatedIds = this.mapping.GetMappedMembers(entity).Where(m => this.mapping.IsPrimaryKey(entity, m) && this.mapping.IsGenerated(entity, m)).ToList();
            if (generatedIds.Count > 0)
            {
                if (map == null || !generatedIds.Any(m => map.ContainsKey(m)))
                {
                    var localMap = new Dictionary<MemberInfo, Expression>();
                    genIdCommand = this.GetGeneratedIdCommand(entity, generatedIds.ToList(), localMap);
                    map = localMap;
                }

                // is this just a retrieval of one generated id member?
                var mex = selector.Body as MemberExpression;
                if (mex != null && this.mapping.IsPrimaryKey(entity, mex.Member) && this.mapping.IsGenerated(entity, mex.Member))
                {
                    if (genIdCommand != null)
                    {
                        // just use the select from the genIdCommand
                        return new ProjectionExpression(
                            genIdCommand.Source,
                            new ColumnExpression(mex.Type, genIdCommand.Variables[0].QueryType, genIdCommand.Source.Alias, genIdCommand.Source.Columns[0].Name),
                            aggregator
                            );
                    }
                    else
                    {
                        TableAlias alias = new TableAlias();
                        var colType = this.GetColumnType(entity, mex.Member);
                        return new ProjectionExpression(
                            new SelectExpression(alias, new[] { new ColumnDeclaration("", map[mex.Member], colType) }, null, null),
                            new ColumnExpression(TypeHelper.GetMemberType(mex.Member), colType, alias, ""),
                            aggregator
                            );
                    }
                }

                where = generatedIds.Select((m, i) =>
                    this.GetMemberExpression(tex, entity, m).Equal(map[m])
                    ).Aggregate((x, y) => x.And(y));
            }
            else
            {
                where = this.GetIdentityCheck(tex, entity, instance);
            }

            Expression typeProjector = this.GetEntityExpression(tex, entity);
            Expression selection = DbExpressionReplacer.Replace(selector.Body, selector.Parameters[0], typeProjector);
            TableAlias newAlias = new TableAlias();
            var pc = ColumnProjector.ProjectColumns(this.translator.Linguist.Language, selection, null, newAlias, tableAlias);
            var pe = new ProjectionExpression(
                new SelectExpression(newAlias, pc.Columns, tex, where),
                pc.Projector,
                aggregator
                );

            if (genIdCommand != null)
            {
                return new BlockCommand(genIdCommand, pe);
            }
            return pe;
        }
예제 #27
0
 public abstract bool IsRelationshipSource(MappingEntity entity, MemberInfo member);
예제 #28
0
 public override IEnumerable<EntityInfo> GetDependingEntities(MappingEntity entity, object instance)
 {
     foreach (var mi in this.GetMappedMembers(entity))
     {
         if (this.IsRelationship(entity, mi) && this.IsRelationshipTarget(entity, mi))
         {
             MappingEntity relatedEntity = this.GetRelatedEntity(entity, mi);
             var value = mi.GetValue(instance);
             if (value != null)
             {
                 var list = value as IList;
                 if (list != null)
                 {
                     foreach (var item in list)
                     {
                         if (item != null)
                         {
                             yield return new EntityInfo(item, relatedEntity);
                         }
                     }
                 }
                 else
                 {
                     yield return new EntityInfo(value, relatedEntity);
                 }
             }
         }
     }
 }
예제 #29
0
 /// <summary>
 /// Determines if a property can be part of an update operation
 /// </summary>
 /// <param name="entity"></param>
 /// <param name="member"></param>
 /// <returns></returns>
 public virtual bool IsUpdatable(MappingEntity entity, MemberInfo member)
 {
     return !this.IsPrimaryKey(entity, member);
 }
예제 #30
0
 /// <summary>
 /// A sequence of all the mapped members
 /// </summary>
 /// <param name="rowType"></param>
 /// <returns></returns>
 public override IEnumerable<MemberInfo> GetMappedMembers(MappingEntity entity)
 {
     //Type type = entity.ElementType.IsInterface ? entity.EntityType : entity.ElementType;
     Type type = entity.EntityType;
     HashSet<MemberInfo> members = new HashSet<MemberInfo>(type.GetFields().Cast<MemberInfo>().Where(m => this.IsMapped(entity, m)));
     members.UnionWith(type.GetProperties().Cast<MemberInfo>().Where(m => this.IsMapped(entity, m)));
     return members.OrderBy(m => m.Name);
 }