/// <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; }
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); }