/// <summary>
 /// Gets values for insert/update
 /// </summary>
 /// <param name="objectToUpsert"></param>
 /// <param name="queryContext"></param>
 /// <param name="update"></param>
 /// <param name="modifiedMembers"></param>
 /// <returns></returns>
 protected virtual UpsertParameters GetUpsertParameters(object objectToUpsert, bool update, IList<MemberInfo> modifiedMembers, QueryContext queryContext)
 {
     var rowType = objectToUpsert.GetType();
     var sqlProvider = queryContext.DataContext.Vendor.SqlProvider;
     var upsertParameters = new UpsertParameters
                                {
                                    Table = queryContext.DataContext.Mapping.GetTable(rowType)
                                };
     foreach (var dataMember in upsertParameters.Table.RowType.PersistentDataMembers)
     {
         var column = sqlProvider.GetColumn(dataMember.MappedName);
         ParameterType type = GetParameterType(objectToUpsert, dataMember, update);
         var memberInfo = dataMember.Member;
         // if the column is generated AND not specified, we may have:
         // - an explicit generation (Expression property is not null, so we add the column)
         // - an implicit generation (Expression property is null
         // in all cases, we want to get the value back
         if (type == ParameterType.Output)
         {
             if (dataMember.Expression != null)
             {
                 upsertParameters.InputColumns.Add(column);
                 upsertParameters.InputValues.Add(dataMember.Expression);
             }
             var setter = (Expression<Action<object, object>>)((o, v) => memberInfo.SetMemberValue(o, v));
             var outputParameter = new ObjectOutputParameterExpression(setter,
                                                                       memberInfo.GetMemberType(),
                                                                       dataMember.Name);
             upsertParameters.OutputParameters.Add(outputParameter);
             upsertParameters.OutputValues.Add(sqlProvider.GetParameterName(outputParameter.Alias));
             upsertParameters.OutputExpressions.Add(dataMember.Expression);
         }
         else // standard column
         {
             var getter = (Expression<Func<object, object>>)(o => memberInfo.GetMemberValue(o));
             var inputParameter = new ObjectInputParameterExpression(
                 getter,
                 memberInfo.GetMemberType(), dataMember.Name);
             if (type == ParameterType.InputPK)
             {
                 upsertParameters.InputPKColumns.Add(column);
                 upsertParameters.InputPKValues.Add(sqlProvider.GetParameterName(inputParameter.Alias));
                 upsertParameters.InputParameters.Add(inputParameter);
             }
             // for a standard column, we keep it only if modifiedMembers contains the specified memberInfo
             // caution: this makes the cache harder to maintain
             else if (modifiedMembers == null || modifiedMembers.Contains(memberInfo))
             {
                 upsertParameters.InputColumns.Add(column);
                 upsertParameters.InputValues.Add(sqlProvider.GetParameterName(inputParameter.Alias));
                 upsertParameters.InputParameters.Add(inputParameter);
             }
         }
     }
     return upsertParameters;
 }
Beispiel #2
0
        protected virtual UpsertParameters GetUpsertParameters <T>(bool update, ICollection <MemberInfo> modifiedMembers, DataContext dataContext)
        {
            var rowType          = typeof(T);
            var sqlProvider      = dataContext.Vendor.SqlProvider;
            var upsertParameters = new UpsertParameters {
                Table = dataContext.Mapping.GetTable(rowType)
            };

            foreach (var dataMember in upsertParameters.Table.RowType.PersistentDataMembers)
            {
                var           column     = sqlProvider.GetColumn(dataMember.MappedName);
                ParameterType type       = GetParameterType(dataMember, update, update ? AutoSync.OnUpdate : AutoSync.OnInsert);
                var           memberInfo = dataMember.Member;
                // if the column is generated AND not specified, we may have:
                // - an explicit generation (Expression property is not null, so we add the column)
                // - an implicit generation (Expression property is null
                // in all cases, we want to get the value back

                var getter         = (Expression <Func <object, object> >)(o => memberInfo.GetMemberValue(o));
                var inputParameter = new ObjectInputParameterExpression(
                    getter,
                    memberInfo.GetMemberType(), dataMember);
                if (dataMember.IsPrimaryKey && (!dataMember.IsDbGenerated))
                {
                    upsertParameters.PKColumns.Add(column);
                    upsertParameters.PKParameters.Add(inputParameter);
                    upsertParameters.PKValues.Add(sqlProvider.GetParameterName(inputParameter.Alias));
                }

                if (type == ParameterType.Output)
                {
                    if (dataMember.Expression != null)
                    {
                        upsertParameters.InputColumns.Add(column);
                        upsertParameters.InputValues.Add(dataMember.Expression);
                    }
                    var setter          = (Expression <Action <object, object> >)((o, v) => memberInfo.SetMemberValue(o, v));
                    var outputParameter = new ObjectOutputParameterExpression(setter,
                                                                              memberInfo.GetMemberType(),
                                                                              dataMember.Name);

                    if ((dataMember.IsPrimaryKey) && (dataMember.IsDbGenerated))
                    {
                        upsertParameters.AutoPKColumns.Add(column);
                    }

                    upsertParameters.OutputColumns.Add(column);
                    upsertParameters.OutputParameters.Add(outputParameter);
                    upsertParameters.OutputValues.Add(sqlProvider.GetParameterName(outputParameter.Alias));
                    upsertParameters.OutputExpressions.Add(dataMember.Expression);
                }
                else   // standard column
                {
                    var isModified = modifiedMembers != null && modifiedMembers.Contains(memberInfo);
                    if (type == ParameterType.InputPK)
                    {
                        upsertParameters.InputPKColumns.Add(column);
                        upsertParameters.InputPKValues.Add(sqlProvider.GetParameterName(inputParameter.Alias));
                        if (isModified)
                        {
                            // stupid! PK is modified, so we will never find the column
                            //upsertParameters.InputColumns.Add(column);
                            //upsertParameters.InputValues.Add(sqlProvider.GetParameterName(inputParameter.Alias+"Old"));
                            upsertParameters.InputParameters.Add(inputParameter);
                        }
                        else
                        {
                            upsertParameters.InputParameters.Add(inputParameter);
                        }
                    }
                    // for a standard column, we keep it only if modifiedMembers contains the specified memberInfo
                    // caution: this makes the cache harder to maintain
                    else if (modifiedMembers == null || isModified)
                    {
                        upsertParameters.InputColumns.Add(column);
                        upsertParameters.InputValues.Add(sqlProvider.GetParameterName(inputParameter.Alias));
                        upsertParameters.InputParameters.Add(inputParameter);
                    }

                    if (type == ParameterType.AutoSync)
                    {
                        var setter          = (Expression <Action <object, object> >)((o, v) => memberInfo.SetMemberValue(o, v));
                        var outputParameter = new ObjectOutputParameterExpression(setter,
                                                                                  memberInfo.GetMemberType(),
                                                                                  dataMember.Name);
                        upsertParameters.OutputColumns.Add(column);
                        upsertParameters.OutputParameters.Add(outputParameter);
                        upsertParameters.OutputValues.Add(sqlProvider.GetParameterName(outputParameter.Alias));
                        upsertParameters.OutputExpressions.Add(dataMember.Expression);
                    }
                }
            }
            return(upsertParameters);
        }