Skip to content
This repository was archived by the owner on Dec 24, 2022. It is now read-only.

Commit 7a6e77d

Browse files
committed
Pass expr.OnlyFields down to indexCache so it doesn't try to attempt greedy match on non selected fields
1 parent 234fa52 commit 7a6e77d

File tree

11 files changed

+216
-95
lines changed

11 files changed

+216
-95
lines changed

src/ServiceStack.OrmLite/Expressions/ReadExpressionCommandExtensions.cs

Lines changed: 22 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -11,59 +11,59 @@ internal static class ReadExpressionCommandExtensions
1111
{
1212
internal static List<T> Select<T>(this IDbCommand dbCmd, Func<SqlExpression<T>, SqlExpression<T>> expression)
1313
{
14-
var expr = dbCmd.GetDialectProvider().SqlExpression<T>();
15-
string sql = expression(expr).SelectInto<T>();
14+
var q = dbCmd.GetDialectProvider().SqlExpression<T>();
15+
string sql = expression(q).SelectInto<T>();
1616

17-
return dbCmd.ExprConvertToList<T>(sql, expr.Params);
17+
return dbCmd.ExprConvertToList<T>(sql, q.Params, onlyFields: q.OnlyFields);
1818
}
1919

2020
internal static List<Into> Select<Into, From>(this IDbCommand dbCmd, Func<SqlExpression<From>, SqlExpression<From>> expression)
2121
{
22-
var expr = dbCmd.GetDialectProvider().SqlExpression<From>();
23-
string sql = expression(expr).SelectInto<Into>();
22+
var q = dbCmd.GetDialectProvider().SqlExpression<From>();
23+
string sql = expression(q).SelectInto<Into>();
2424

25-
return dbCmd.ExprConvertToList<Into>(sql, expr.Params);
25+
return dbCmd.ExprConvertToList<Into>(sql, q.Params, onlyFields: q.OnlyFields);
2626
}
2727

28-
internal static List<Into> Select<Into, From>(this IDbCommand dbCmd, SqlExpression<From> expression)
28+
internal static List<Into> Select<Into, From>(this IDbCommand dbCmd, SqlExpression<From> q)
2929
{
30-
string sql = expression.SelectInto<Into>();
31-
return dbCmd.ExprConvertToList<Into>(sql, expression.Params);
30+
string sql = q.SelectInto<Into>();
31+
return dbCmd.ExprConvertToList<Into>(sql, q.Params, onlyFields: q.OnlyFields);
3232
}
3333

34-
internal static List<T> Select<T>(this IDbCommand dbCmd, SqlExpression<T> expression)
34+
internal static List<T> Select<T>(this IDbCommand dbCmd, SqlExpression<T> q)
3535
{
36-
string sql = expression.SelectInto<T>();
36+
string sql = q.SelectInto<T>();
3737

38-
return dbCmd.ExprConvertToList<T>(sql, expression.Params);
38+
return dbCmd.ExprConvertToList<T>(sql, q.Params, onlyFields: q.OnlyFields);
3939
}
4040

4141
internal static List<T> Select<T>(this IDbCommand dbCmd, Expression<Func<T, bool>> predicate)
4242
{
43-
var expr = dbCmd.GetDialectProvider().SqlExpression<T>();
44-
string sql = expr.Where(predicate).SelectInto<T>();
43+
var q = dbCmd.GetDialectProvider().SqlExpression<T>();
44+
string sql = q.Where(predicate).SelectInto<T>();
4545

46-
return dbCmd.ExprConvertToList<T>(sql, expr.Params);
46+
return dbCmd.ExprConvertToList<T>(sql, q.Params);
4747
}
4848

4949
internal static T Single<T>(this IDbCommand dbCmd, Func<SqlExpression<T>, SqlExpression<T>> expression)
5050
{
51-
var expr = dbCmd.GetDialectProvider().SqlExpression<T>();
52-
return dbCmd.Single(expression(expr));
51+
var q = dbCmd.GetDialectProvider().SqlExpression<T>();
52+
return dbCmd.Single(expression(q));
5353
}
5454

5555
internal static T Single<T>(this IDbCommand dbCmd, Expression<Func<T, bool>> predicate)
5656
{
57-
var ev = dbCmd.GetDialectProvider().SqlExpression<T>();
57+
var q = dbCmd.GetDialectProvider().SqlExpression<T>();
5858

59-
return Single(dbCmd, ev.Where(predicate));
59+
return Single(dbCmd, q.Where(predicate));
6060
}
6161

62-
internal static T Single<T>(this IDbCommand dbCmd, SqlExpression<T> expression)
62+
internal static T Single<T>(this IDbCommand dbCmd, SqlExpression<T> q)
6363
{
64-
string sql = expression.Limit(1).SelectInto<T>();
64+
string sql = q.Limit(1).SelectInto<T>();
6565

66-
return dbCmd.ExprConvertTo<T>(sql, expression.Params);
66+
return dbCmd.ExprConvertTo<T>(sql, q.Params, onlyFields:q.OnlyFields);
6767
}
6868

6969
public static TKey Scalar<T, TKey>(this IDbCommand dbCmd, SqlExpression<T> expression)

src/ServiceStack.OrmLite/Expressions/SqlExpression.Join.cs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,7 @@ private SqlExpression<T> InternalJoin(string joinType,
155155

156156
public string SelectInto<TModel>()
157157
{
158-
if ((CustomSelect && onlyFields == null) || (typeof(TModel) == typeof(T) && !PrefixFieldWithTableName))
158+
if ((CustomSelect && OnlyFields == null) || (typeof(TModel) == typeof(T) && !PrefixFieldWithTableName))
159159
{
160160
return ToSelectStatement();
161161
}
@@ -181,7 +181,7 @@ public string SelectInto<TModel>()
181181
{
182182
if (tableFieldDef.Name == fieldDef.Name)
183183
{
184-
if (onlyFields != null && !onlyFields.Contains(fieldDef.Name))
184+
if (OnlyFields != null && !OnlyFields.Contains(fieldDef.Name))
185185
continue;
186186

187187
found = true;
@@ -215,7 +215,7 @@ public string SelectInto<TModel>()
215215

216216
if (matchingField != null)
217217
{
218-
if (onlyFields != null && !onlyFields.Contains(fieldDef.Name))
218+
if (OnlyFields != null && !OnlyFields.Contains(fieldDef.Name))
219219
continue;
220220

221221
if (sbSelect.Length > 0)

src/ServiceStack.OrmLite/Expressions/SqlExpression.cs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ public abstract partial class SqlExpression<T> : ISqlExpression, IHasUntypedSqlE
2121
private string groupBy = string.Empty;
2222
private string havingExpression;
2323
private string orderBy = string.Empty;
24-
private HashSet<string> onlyFields = null;
24+
protected internal HashSet<string> OnlyFields { get; set; }
2525

2626
public List<string> UpdateFields { get; set; }
2727
public List<string> InsertFields { get; set; }
@@ -72,7 +72,7 @@ protected virtual SqlExpression<T> CopyTo(SqlExpression<T> to)
7272
to.groupBy = groupBy;
7373
to.havingExpression = havingExpression;
7474
to.orderBy = orderBy;
75-
to.onlyFields = onlyFields != null ? new HashSet<string>(onlyFields) : null;
75+
to.OnlyFields = OnlyFields != null ? new HashSet<string>(OnlyFields) : null;
7676
to.UpdateFields = UpdateFields;
7777
to.InsertFields = InsertFields;
7878
to.modelDef = modelDef;
@@ -114,7 +114,7 @@ public virtual SqlExpression<T> UnsafeSelect(string rawSelect)
114114
{
115115
this.selectExpression = "SELECT " + rawSelect;
116116
this.CustomSelect = true;
117-
onlyFields = null;
117+
OnlyFields = null;
118118
}
119119
return this;
120120
}
@@ -146,7 +146,7 @@ public virtual SqlExpression<T> Select(string[] fields)
146146
}
147147

148148
UnsafeSelect(sb.ToString());
149-
onlyFields = new HashSet<string>(fields, StringComparer.OrdinalIgnoreCase);
149+
OnlyFields = new HashSet<string>(fields, StringComparer.OrdinalIgnoreCase);
150150

151151
return this;
152152
}
@@ -1526,7 +1526,7 @@ protected object GetQuotedFalseValue()
15261526

15271527
private void BuildSelectExpression(string fields, bool distinct)
15281528
{
1529-
onlyFields = null;
1529+
OnlyFields = null;
15301530
selectDistinct = distinct;
15311531

15321532
selectExpression = string.Format("SELECT {0}{1}",

src/ServiceStack.OrmLite/ModelDefinition.cs

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -118,19 +118,25 @@ public Dictionary<string, FieldDefinition> GetFieldDefinitionMap(Func<string, st
118118

119119
public FieldDefinition GetFieldDefinition<T>(Expression<Func<T, object>> field)
120120
{
121-
var fn = GetFieldName(field);
122-
return FieldDefinitions.First(f => f.Name == fn);
121+
return GetFieldDefinition(GetFieldName(field));
123122
}
124123

125124
public FieldDefinition GetFieldDefinition(string fieldName)
126125
{
127-
return FieldDefinitions.FirstOrDefault(f => f.Name == fieldName);
126+
if (fieldName != null)
127+
{
128+
foreach (var f in FieldDefinitionsArray)
129+
{
130+
if (string.Equals(f.Name, fieldName, StringComparison.OrdinalIgnoreCase))
131+
return f;
132+
}
133+
}
134+
return null;
128135
}
129136

130137
string GetFieldName<T>(Expression<Func<T, object>> field)
131138
{
132-
133-
var lambda = (field as LambdaExpression);
139+
var lambda = field as LambdaExpression;
134140
if (lambda.Body.NodeType == ExpressionType.MemberAccess)
135141
{
136142
var me = lambda.Body as MemberExpression;

src/ServiceStack.OrmLite/OrmLiteResultsFilterExtensions.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -116,7 +116,7 @@ public static IDbDataParameter PopulateWith(this IDbDataParameter to, IDbDataPar
116116
return to;
117117
}
118118

119-
internal static List<T> ExprConvertToList<T>(this IDbCommand dbCmd, string sql = null, IEnumerable<IDbDataParameter> sqlParams = null)
119+
internal static List<T> ExprConvertToList<T>(this IDbCommand dbCmd, string sql = null, IEnumerable<IDbDataParameter> sqlParams = null, HashSet<string> onlyFields=null)
120120
{
121121
if (sql != null)
122122
dbCmd.CommandText = sql;
@@ -130,7 +130,7 @@ internal static List<T> ExprConvertToList<T>(this IDbCommand dbCmd, string sql =
130130

131131
using (var reader = dbCmd.ExecReader(dbCmd.CommandText))
132132
{
133-
return reader.ConvertToList<T>(dbCmd.GetDialectProvider());
133+
return reader.ConvertToList<T>(dbCmd.GetDialectProvider(), onlyFields:onlyFields);
134134
}
135135
}
136136

@@ -257,7 +257,7 @@ public static long ExecLongScalar(this IDbCommand dbCmd, string sql = null)
257257
return dbCmd.LongScalar();
258258
}
259259

260-
internal static T ExprConvertTo<T>(this IDbCommand dbCmd, string sql = null, IEnumerable<IDbDataParameter> sqlParams = null)
260+
internal static T ExprConvertTo<T>(this IDbCommand dbCmd, string sql = null, IEnumerable<IDbDataParameter> sqlParams = null, HashSet<string> onlyFields = null)
261261
{
262262
if (sql != null)
263263
dbCmd.CommandText = sql;
@@ -271,7 +271,7 @@ internal static T ExprConvertTo<T>(this IDbCommand dbCmd, string sql = null, IEn
271271

272272
using (var reader = dbCmd.ExecReader(dbCmd.CommandText))
273273
{
274-
return reader.ConvertTo<T>(dbCmd.GetDialectProvider());
274+
return reader.ConvertTo<T>(dbCmd.GetDialectProvider(), onlyFields: onlyFields);
275275
}
276276
}
277277

src/ServiceStack.OrmLite/OrmLiteUtils.cs

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ public static bool IsScalar<T>()
5858
return typeof(T).IsValueType || typeof(T) == typeof(string);
5959
}
6060

61-
public static T ConvertTo<T>(this IDataReader reader, IOrmLiteDialectProvider dialectProvider)
61+
public static T ConvertTo<T>(this IDataReader reader, IOrmLiteDialectProvider dialectProvider, HashSet<string> onlyFields=null)
6262
{
6363
using (reader)
6464
{
@@ -71,7 +71,7 @@ public static T ConvertTo<T>(this IDataReader reader, IOrmLiteDialectProvider di
7171
return (T)(object)reader.ConvertToDictionaryObjects();
7272

7373
var row = CreateInstance<T>();
74-
var indexCache = reader.GetIndexFieldsCache(ModelDefinition<T>.Definition, dialectProvider);
74+
var indexCache = reader.GetIndexFieldsCache(ModelDefinition<T>.Definition, dialectProvider, onlyFields: onlyFields);
7575
var values = new object[reader.FieldCount];
7676
row.PopulateWithSqlReader(dialectProvider, reader, indexCache, values);
7777
return row;
@@ -100,7 +100,7 @@ public static Dictionary<string, object> ConvertToDictionaryObjects(this IDataRe
100100
return row;
101101
}
102102

103-
public static List<T> ConvertToList<T>(this IDataReader reader, IOrmLiteDialectProvider dialectProvider)
103+
public static List<T> ConvertToList<T>(this IDataReader reader, IOrmLiteDialectProvider dialectProvider, HashSet<string> onlyFields=null)
104104
{
105105
if (typeof(T) == typeof(List<object>))
106106
{
@@ -133,7 +133,7 @@ public static List<T> ConvertToList<T>(this IDataReader reader, IOrmLiteDialectP
133133
var to = new List<T>();
134134
using (reader)
135135
{
136-
var indexCache = reader.GetIndexFieldsCache(ModelDefinition<T>.Definition, dialectProvider);
136+
var indexCache = reader.GetIndexFieldsCache(ModelDefinition<T>.Definition, dialectProvider, onlyFields:onlyFields);
137137
var values = new object[reader.FieldCount];
138138
while (reader.Read())
139139
{
@@ -351,7 +351,10 @@ public static SqlInValues SqlInValues<T>(this T[] values, IOrmLiteDialectProvide
351351
return new SqlInValues(values, dialect);
352352
}
353353

354-
public static Tuple<FieldDefinition, int, IOrmLiteConverter>[] GetIndexFieldsCache(this IDataReader reader, ModelDefinition modelDefinition, IOrmLiteDialectProvider dialect)
354+
public static Tuple<FieldDefinition, int, IOrmLiteConverter>[] GetIndexFieldsCache(this IDataReader reader,
355+
ModelDefinition modelDefinition,
356+
IOrmLiteDialectProvider dialect,
357+
HashSet<string> onlyFields = null)
355358
{
356359
var cache = new List<Tuple<FieldDefinition, int, IOrmLiteConverter>>();
357360
var ignoredFields = modelDefinition.IgnoredFieldDefinitions;
@@ -370,12 +373,13 @@ public static Tuple<FieldDefinition, int, IOrmLiteConverter>[] GetIndexFieldsCac
370373
}
371374
}
372375

373-
if (remainingFieldDefs.Count > 0)
376+
if (remainingFieldDefs.Count > 0 && onlyFields == null)
374377
{
375378
var dbFieldMap = new Dictionary<string, int>(StringComparer.InvariantCultureIgnoreCase);
376379
for (var i = 0; i < reader.FieldCount; i++)
377380
{
378-
dbFieldMap[reader.GetName(i)] = i;
381+
var fieldName = reader.GetName(i);
382+
dbFieldMap[fieldName] = i;
379383
}
380384

381385
foreach (var fieldDef in remainingFieldDefs)

src/ServiceStack.OrmLite/Support/LoadList.cs

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ namespace ServiceStack.OrmLite.Support
1212
internal abstract class LoadList<Into, From>
1313
{
1414
protected IDbCommand dbCmd;
15-
protected SqlExpression<From> expr;
15+
protected SqlExpression<From> q;
1616

1717
protected IOrmLiteDialectProvider dialectProvider;
1818
protected List<Into> parentResults;
@@ -30,23 +30,23 @@ public List<Into> ParentResults
3030
get { return parentResults; }
3131
}
3232

33-
protected LoadList(IDbCommand dbCmd, SqlExpression<From> expr)
33+
protected LoadList(IDbCommand dbCmd, SqlExpression<From> q)
3434
{
3535
dialectProvider = dbCmd.GetDialectProvider();
3636

37-
if (expr == null)
38-
expr = dialectProvider.SqlExpression<From>();
37+
if (q == null)
38+
q = dialectProvider.SqlExpression<From>();
3939

4040
this.dbCmd = dbCmd;
41-
this.expr = expr;
41+
this.q = q;
4242

43-
var sql = expr.SelectInto<Into>();
44-
parentResults = dbCmd.ExprConvertToList<Into>(sql, expr.Params);
43+
var sql = q.SelectInto<Into>();
44+
parentResults = dbCmd.ExprConvertToList<Into>(sql, q.Params, onlyFields:q.OnlyFields);
4545

4646
modelDef = ModelDefinition<Into>.Definition;
4747
fieldDefs = modelDef.AllFieldDefinitionsArray.Where(x => x.IsReference).ToList();
4848

49-
subSql = dialectProvider.GetLoadChildrenSubSelect(expr);
49+
subSql = dialectProvider.GetLoadChildrenSubSelect(q);
5050
}
5151

5252
protected string GetRefListSql(ModelDefinition refModelDef, FieldDefinition refField)
@@ -90,9 +90,9 @@ protected void SetListChildResults(FieldDefinition fieldDef, Type refType, IList
9090
protected string GetRefSelfSql(ModelDefinition modelDef, FieldDefinition refSelf, ModelDefinition refModelDef)
9191
{
9292
//Load Self Table.RefTableId PK
93-
expr.Select(dialectProvider.GetQuotedColumnName(modelDef, refSelf));
93+
q.Select(dialectProvider.GetQuotedColumnName(modelDef, refSelf));
9494

95-
var subSqlRef = expr.ToSelectStatement();
95+
var subSqlRef = q.ToSelectStatement();
9696

9797
var sqlRef = "SELECT {0} FROM {1} WHERE {2} IN ({3})".Fmt(
9898
dialectProvider.GetColumnNames(refModelDef),
@@ -191,7 +191,7 @@ protected void SetRefFieldChildResults(FieldDefinition fieldDef, FieldDefinition
191191

192192
internal class LoadListSync<Into, From> : LoadList<Into, From>
193193
{
194-
public LoadListSync(IDbCommand dbCmd, SqlExpression<From> expr) : base(dbCmd, expr) {}
194+
public LoadListSync(IDbCommand dbCmd, SqlExpression<From> q) : base(dbCmd, q) {}
195195

196196
public void SetRefFieldList(FieldDefinition fieldDef, Type refType)
197197
{

0 commit comments

Comments
 (0)