/// <summary>
 /// Creates or gets a DELETE query
 /// </summary>
 /// <param name="objectToDelete"></param>
 /// <param name="queryContext"></param>
 /// <returns></returns>
 public DeleteQuery GetDeleteQuery(object objectToDelete, QueryContext queryContext)
 {
     var sqlProvider = queryContext.DataContext.Vendor.SqlProvider;
     var rowType = objectToDelete.GetType();
     var table = queryContext.DataContext.Mapping.GetTable(rowType);
     var deleteParameters = new List<ObjectInputParameterExpression>();
     var pkColumns = new List<string>();
     var pkValues = new List<string>();
     foreach (var pkMember in table.RowType.IdentityMembers)
     {
         var memberInfo = pkMember.Member;
         var getter = (Expression<Func<object, object>>)(o => memberInfo.GetMemberValue(o));
         var inputParameter = new ObjectInputParameterExpression(
             getter,
             memberInfo.GetMemberType(), pkMember.Name);
         var column = sqlProvider.GetColumn(pkMember.MappedName);
         pkColumns.Add(column);
         pkValues.Add(sqlProvider.GetParameterName(inputParameter.Alias));
         deleteParameters.Add(inputParameter);
     }
     var deleteSql = sqlProvider.GetDelete(sqlProvider.GetTable(table.TableName), pkColumns, pkValues);
     queryContext.DataContext.Logger.Write(Level.Debug, "Delete SQL: {0}", deleteSql);
     return new DeleteQuery(queryContext.DataContext, deleteSql, deleteParameters);
 }
 /// <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;
 }