protected virtual SqlPlaceHolder CreateSqlPlaceHolder(ExternalValueExpression extValue) { var dataType = extValue.SourceExpression.Type; var driver = this.DbModel.Driver; var typeRegistry = driver.TypeRegistry; var valueReader = BuildParameterValueReader(extValue.SourceExpression); SqlPlaceHolder ph; if (dataType.IsListOfDbPrimitive(out var elemType)) { // list parameter var elemTypeDef = typeRegistry.GetDbTypeDef(elemType); Util.Check(elemTypeDef != null, "Failed to match DB type for CLR type {0}", elemType); ph = new SqlListParamPlaceHolder(elemType, elemTypeDef, valueReader, // ToLiteral formatLiteral: list => driver.SqlDialect.ListToLiteral(list, elemTypeDef) ); } else { //regular linq parameter var typeDef = typeRegistry.GetDbTypeDef(dataType); Util.Check(typeDef != null, "Failed to find DB type for linq parameter of type {0}", dataType); var dbConv = typeRegistry.GetDbValueConverter(typeDef.ColumnOutType, dataType); Util.Check(dbConv != null, "Failed to find converter from type {0} to type {1}", dataType, typeDef.ColumnOutType); ph = new SqlLinqParamPlaceHolder(dataType, valueReader, dbConv.PropertyToColumn, typeDef.ToLiteral); } this.PlaceHolders.Add(ph); return(ph); }
private string FormatLinqPlaceHolder(SqlLinqParamPlaceHolder ph, object arg) { var value = ph.ValueReader((object[])arg); var dbValue = ph.ValueToDbValue(value) ?? DBNull.Value; //move it into converters? currently no-conv does not do this var useLiteral = ShouldUseLiteral(dbValue); if (useLiteral) { return(FormatAsLiteral(ph, dbValue)); } else { var prm = _sqlDialect.AddDbParameter(_dbCommand, ph, dbValue); var fmt = ph.FormatParameter; return(fmt == null ? prm.ParameterName : fmt(prm)); } }