Skip to content

Commit 2fcc289

Browse files
committed
feat: order guarantees and support for includes
1 parent 4fb79e8 commit 2fcc289

File tree

10 files changed

+347
-580
lines changed

10 files changed

+347
-580
lines changed

src/QueryableValues.SqlServer/DeferredValues.cs

Lines changed: 17 additions & 92 deletions
Original file line numberDiff line numberDiff line change
@@ -4,27 +4,31 @@
44

55
namespace BlazarTech.QueryableValues
66
{
7-
internal abstract class DeferredValues<T> : IConvertible
7+
internal sealed class DeferredValues<T, T2> : IDeferredValues
88
where T : notnull
9+
where T2 : notnull
910
{
10-
protected readonly ISerializer _serializer;
11-
protected readonly IEnumerable<T> _values;
11+
private readonly ISerializer _serializer;
12+
private readonly ValuesWrapper<T, T2> _valuesWrapper;
13+
14+
public IReadOnlyList<EntityPropertyMapping> Mappings { get; }
1215

1316
public bool HasCount
1417
{
1518
get
1619
{
17-
return _values.TryGetNonEnumeratedCount(out _);
20+
return _valuesWrapper.OriginalValues.TryGetNonEnumeratedCount(out _);
1821
}
1922
}
2023

21-
public DeferredValues(ISerializer serializer, IEnumerable<T> values)
24+
public DeferredValues(ISerializer serializer, ValuesWrapper<T, T2> valuesWrapper)
2225
{
2326
_serializer = serializer;
24-
_values = values;
27+
_valuesWrapper = valuesWrapper;
28+
Mappings = EntityPropertyMapping.GetMappings<T2>();
2529
}
2630

27-
public abstract string ToString(IFormatProvider? provider);
31+
public string ToString(IFormatProvider? provider) => _serializer.Serialize(_valuesWrapper.ProjectedValues, Mappings);
2832

2933
public TypeCode GetTypeCode() => throw new NotImplementedException();
3034
public bool ToBoolean(IFormatProvider? provider) => throw new NotImplementedException();
@@ -38,13 +42,14 @@ public DeferredValues(ISerializer serializer, IEnumerable<T> values)
3842

3943
public long ToInt64(IFormatProvider? provider)
4044
{
41-
if (_values.TryGetNonEnumeratedCount(out int count))
45+
if (_valuesWrapper.OriginalValues.TryGetNonEnumeratedCount(out int count))
4246
{
4347
return count;
4448
}
4549
else
4650
{
47-
throw new InvalidOperationException("Count not available. (how did this happen?)");
51+
// Count not available. How did this happen?
52+
return int.MaxValue;
4853
}
4954
}
5055

@@ -56,89 +61,9 @@ public long ToInt64(IFormatProvider? provider)
5661
public ulong ToUInt64(IFormatProvider? provider) => throw new NotImplementedException();
5762
}
5863

59-
internal sealed class DeferredByteValues : DeferredValues<byte>
60-
{
61-
public DeferredByteValues(ISerializer serializer, IEnumerable<byte> values) : base(serializer, values) { }
62-
public override string ToString(IFormatProvider? provider) => _serializer.Serialize(_values);
63-
}
64-
65-
internal sealed class DeferredInt16Values : DeferredValues<short>
66-
{
67-
public DeferredInt16Values(ISerializer serializer, IEnumerable<short> values) : base(serializer, values) { }
68-
public override string ToString(IFormatProvider? provider) => _serializer.Serialize(_values);
69-
}
70-
71-
internal sealed class DeferredInt32Values : DeferredValues<int>
72-
{
73-
public DeferredInt32Values(ISerializer serializer, IEnumerable<int> values) : base(serializer, values) { }
74-
public override string ToString(IFormatProvider? provider) => _serializer.Serialize(_values);
75-
}
76-
77-
internal sealed class DeferredInt64Values : DeferredValues<long>
78-
{
79-
public DeferredInt64Values(ISerializer serializer, IEnumerable<long> values) : base(serializer, values) { }
80-
public override string ToString(IFormatProvider? provider) => _serializer.Serialize(_values);
81-
}
82-
83-
internal sealed class DeferredDecimalValues : DeferredValues<decimal>
84-
{
85-
public DeferredDecimalValues(ISerializer serializer, IEnumerable<decimal> values) : base(serializer, values) { }
86-
public override string ToString(IFormatProvider? provider) => _serializer.Serialize(_values);
87-
}
88-
89-
internal sealed class DeferredSingleValues : DeferredValues<float>
90-
{
91-
public DeferredSingleValues(ISerializer serializer, IEnumerable<float> values) : base(serializer, values) { }
92-
public override string ToString(IFormatProvider? provider) => _serializer.Serialize(_values);
93-
}
94-
95-
internal sealed class DeferredDoubleValues : DeferredValues<double>
96-
{
97-
public DeferredDoubleValues(ISerializer serializer, IEnumerable<double> values) : base(serializer, values) { }
98-
public override string ToString(IFormatProvider? provider) => _serializer.Serialize(_values);
99-
}
100-
101-
internal sealed class DeferredDateTimeValues : DeferredValues<DateTime>
102-
{
103-
public DeferredDateTimeValues(ISerializer serializer, IEnumerable<DateTime> values) : base(serializer, values) { }
104-
public override string ToString(IFormatProvider? provider) => _serializer.Serialize(_values);
105-
}
106-
107-
internal sealed class DeferredDateTimeOffsetValues : DeferredValues<DateTimeOffset>
64+
internal interface IDeferredValues : IConvertible
10865
{
109-
public DeferredDateTimeOffsetValues(ISerializer serializer, IEnumerable<DateTimeOffset> values) : base(serializer, values) { }
110-
public override string ToString(IFormatProvider? provider) => _serializer.Serialize(_values);
111-
}
112-
113-
internal sealed class DeferredGuidValues : DeferredValues<Guid>
114-
{
115-
public DeferredGuidValues(ISerializer serializer, IEnumerable<Guid> values) : base(serializer, values) { }
116-
public override string ToString(IFormatProvider? provider) => _serializer.Serialize(_values);
117-
}
118-
119-
internal sealed class DeferredCharValues : DeferredValues<char>
120-
{
121-
public DeferredCharValues(ISerializer serializer, IEnumerable<char> values) : base(serializer, values) { }
122-
public override string ToString(IFormatProvider? provider) => _serializer.Serialize(_values);
123-
}
124-
125-
internal sealed class DeferredStringValues : DeferredValues<string>
126-
{
127-
public DeferredStringValues(ISerializer serializer, IEnumerable<string> values) : base(serializer, values) { }
128-
public override string ToString(IFormatProvider? provider) => _serializer.Serialize(_values);
129-
}
130-
131-
internal sealed class DeferredEntityValues<T> : DeferredValues<T>
132-
where T : notnull
133-
{
134-
private readonly IReadOnlyList<EntityPropertyMapping> _mappings;
135-
136-
public DeferredEntityValues(ISerializer serializer, IEnumerable<T> values, IReadOnlyList<EntityPropertyMapping> mappings)
137-
: base(serializer, values)
138-
{
139-
_mappings = mappings;
140-
}
141-
142-
public override string ToString(IFormatProvider? provider) => _serializer.Serialize(_values, _mappings);
66+
IReadOnlyList<EntityPropertyMapping> Mappings { get; }
67+
bool HasCount { get; }
14368
}
14469
}

src/QueryableValues.SqlServer/EntityPropertyMapping.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ internal sealed class EntityPropertyMapping
1010
{
1111
internal static readonly IReadOnlyDictionary<Type, EntityPropertyTypeName> SimpleTypes;
1212

13-
private static readonly PropertyInfo[] EntityProperties = typeof(QueryableValuesEntity).GetProperties();
13+
private static readonly PropertyInfo[] EntityProperties = typeof(QueryableValuesEntity).GetProperties().Where(i => i.Name != QueryableValuesEntity.IndexPropertyName).ToArray();
1414
private static readonly ConcurrentDictionary<Type, IReadOnlyList<EntityPropertyMapping>> MappingCache = new ConcurrentDictionary<Type, IReadOnlyList<EntityPropertyMapping>>();
1515

1616
public PropertyInfo Source { get; }

src/QueryableValues.SqlServer/ModelCustomizer.cs

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -43,22 +43,22 @@ private static void SetupEntity(ModelBuilder modelBuilder)
4343
modelBuilder
4444
.Entity<QueryableValuesEntity>(entity =>
4545
{
46-
SetDefaultPrecision(entity.Property(p => p.Decimal0));
47-
SetDefaultPrecision(entity.Property(p => p.Decimal1));
48-
SetDefaultPrecision(entity.Property(p => p.Decimal2));
49-
SetDefaultPrecision(entity.Property(p => p.Decimal3));
50-
SetDefaultPrecision(entity.Property(p => p.Decimal4));
51-
SetDefaultPrecision(entity.Property(p => p.Decimal5));
52-
SetDefaultPrecision(entity.Property(p => p.Decimal6));
53-
SetDefaultPrecision(entity.Property(p => p.Decimal7));
54-
SetDefaultPrecision(entity.Property(p => p.Decimal8));
55-
SetDefaultPrecision(entity.Property(p => p.Decimal9));
46+
SetDefaultPrecision(entity.Property(p => p.M));
47+
SetDefaultPrecision(entity.Property(p => p.M1));
48+
SetDefaultPrecision(entity.Property(p => p.M2));
49+
SetDefaultPrecision(entity.Property(p => p.M3));
50+
SetDefaultPrecision(entity.Property(p => p.M4));
51+
SetDefaultPrecision(entity.Property(p => p.M5));
52+
SetDefaultPrecision(entity.Property(p => p.M6));
53+
SetDefaultPrecision(entity.Property(p => p.M7));
54+
SetDefaultPrecision(entity.Property(p => p.M8));
55+
SetDefaultPrecision(entity.Property(p => p.M9));
5656

5757
// By mapping to a fake view, we stop EF from including these entities during
5858
// SQL generation in migrations and by the Create and Drop apis in DbContext.Database.
5959
entity
6060
.ToView(nameof(QueryableValuesEntity))
61-
.HasNoKey();
61+
.HasKey(i => i.X);
6262
});
6363
}
6464

0 commit comments

Comments
 (0)