protected virtual void SetOutputParameterValue(object target, ObjectOutputParameterExpression outputParameter, object value) { // depending on vendor, we can have DBNull or null // so we handle both if (value is DBNull || value == null) { outputParameter.SetValue(target, null); } else { outputParameter.SetValue(target, TypeConvert.To(value, outputParameter.ValueType)); } }
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); }