Commit d9fedd9b authored by Marc Gravell's avatar Marc Gravell

Fix behavior when removing values/keys from DapperRow

parent 3bfebc24
...@@ -1319,10 +1319,22 @@ public DapperRow(DapperTable table, object[] values) ...@@ -1319,10 +1319,22 @@ public DapperRow(DapperTable table, object[] values)
this.table = table; this.table = table;
this.values = values; this.values = values;
} }
private sealed class DeadValue
int ICollection<KeyValuePair<string,object>>.Count {
public static readonly DeadValue Default = new DeadValue();
private DeadValue() { }
}
int ICollection<KeyValuePair<string, object>>.Count
{ {
get { return table.FieldCount; } get
{
int count = 0;
for (int i = 0; i < values.Length; i++)
{
if (!(values[i] is DeadValue)) count++;
}
return count;
}
} }
public bool TryGetValue(string name, out object value) public bool TryGetValue(string name, out object value)
...@@ -1335,40 +1347,24 @@ public bool TryGetValue(string name, out object value) ...@@ -1335,40 +1347,24 @@ public bool TryGetValue(string name, out object value)
} }
// exists, **even if** we don't have a value; consider table rows heterogeneous // exists, **even if** we don't have a value; consider table rows heterogeneous
value = index < values.Length ? values[index] : null; value = index < values.Length ? values[index] : null;
if (value is DeadValue)
{ // pretend it isn't here
value = null;
return false;
}
return true; return true;
} }
/* public object SetValue(string name, object value)
{
var index = Table.IndexOfName(name);
if (index == -1)
{
if (m_additionalValues == null)
{
m_additionalValues = new Dictionary<string, object>();
}
m_additionalValues[name ?? ""] = value;
return value;
}
return SetFieldValueImpl(index, value);
}*/
public override string ToString() public override string ToString()
{ {
var sb = new StringBuilder("{DapperRow"); var sb = new StringBuilder("{DapperRow");
foreach (var kv in this) foreach (var kv in this)
{ {
var value = kv.Value; var value = kv.Value;
sb.Append(", "); sb.Append(", ").Append(kv.Key);
sb.Append(kv.Key);
if (value != null) if (value != null)
{ {
sb.Append(" = '"); sb.Append(" = '").Append(kv.Value).Append('\'');
sb.Append(kv.Value);
sb.Append('\'');
} }
else else
{ {
...@@ -1376,11 +1372,11 @@ public override string ToString() ...@@ -1376,11 +1372,11 @@ public override string ToString()
} }
} }
sb.Append('}'); return sb.Append('}').ToString();
return sb.ToString();
} }
public System.Dynamic.DynamicMetaObject GetMetaObject(System.Linq.Expressions.Expression parameter) System.Dynamic.DynamicMetaObject System.Dynamic.IDynamicMetaObjectProvider.GetMetaObject(
System.Linq.Expressions.Expression parameter)
{ {
return new DapperRowMetaObject(parameter, System.Dynamic.BindingRestrictions.Empty, this); return new DapperRowMetaObject(parameter, System.Dynamic.BindingRestrictions.Empty, this);
} }
...@@ -1391,7 +1387,10 @@ public System.Dynamic.DynamicMetaObject GetMetaObject(System.Linq.Expressions.Ex ...@@ -1391,7 +1387,10 @@ public System.Dynamic.DynamicMetaObject GetMetaObject(System.Linq.Expressions.Ex
for (var i = 0; i < names.Length; i++) for (var i = 0; i < names.Length; i++)
{ {
object value = i < values.Length ? values[i] : null; object value = i < values.Length ? values[i] : null;
yield return new KeyValuePair<string, object>(names[i], value); if (!(value is DeadValue))
{
yield return new KeyValuePair<string, object>(names[i], value);
}
} }
} }
...@@ -1410,7 +1409,8 @@ IEnumerator IEnumerable.GetEnumerator() ...@@ -1410,7 +1409,8 @@ IEnumerator IEnumerable.GetEnumerator()
void ICollection<KeyValuePair<string, object>>.Clear() void ICollection<KeyValuePair<string, object>>.Clear()
{ // removes values for **this row**, but doesn't change the fundamental table { // removes values for **this row**, but doesn't change the fundamental table
values = new object[0]; for (int i = 0; i < values.Length; i++)
values[i] = DeadValue.Default;
} }
bool ICollection<KeyValuePair<string, object>>.Contains(KeyValuePair<string, object> item) bool ICollection<KeyValuePair<string, object>>.Contains(KeyValuePair<string, object> item)
...@@ -1444,7 +1444,9 @@ IEnumerator IEnumerable.GetEnumerator() ...@@ -1444,7 +1444,9 @@ IEnumerator IEnumerable.GetEnumerator()
bool IDictionary<string, object>.ContainsKey(string key) bool IDictionary<string, object>.ContainsKey(string key)
{ {
return table.FieldExists(key); int index = table.IndexOfName(key);
if (index < 0 || index >= values.Length || values[index] is DeadValue) return false;
return true;
} }
void IDictionary<string, object>.Add(string key, object value) void IDictionary<string, object>.Add(string key, object value)
...@@ -1456,8 +1458,9 @@ IEnumerator IEnumerable.GetEnumerator() ...@@ -1456,8 +1458,9 @@ IEnumerator IEnumerable.GetEnumerator()
bool IDictionary<string, object>.Remove(string key) bool IDictionary<string, object>.Remove(string key)
{ {
int index = table.IndexOfName(key); int index = table.IndexOfName(key);
if(index >= 0 && index < values.Length) values[index] = null; if (index < 0 || index >= values.Length || values[index] is DeadValue) return false;
return index >= 0; values[index] = DeadValue.Default;
return true;
} }
object IDictionary<string, object>.this[string key] object IDictionary<string, object>.this[string key]
...@@ -1478,7 +1481,7 @@ public object SetValue(string key, object value) ...@@ -1478,7 +1481,7 @@ public object SetValue(string key, object value)
// grow it to the full width of the table // grow it to the full width of the table
Array.Resize(ref values, table.FieldCount); Array.Resize(ref values, table.FieldCount);
} }
return values[index] = value; return values[index] = value;
} }
ICollection<string> IDictionary<string, object>.Keys ICollection<string> IDictionary<string, object>.Keys
......
...@@ -2127,7 +2127,18 @@ public void TestDynamicMutation() ...@@ -2127,7 +2127,18 @@ public void TestDynamicMutation()
var obj = connection.Query("select 1 as [a], 2 as [b], 3 as [c]").Single(); var obj = connection.Query("select 1 as [a], 2 as [b], 3 as [c]").Single();
((int)obj.a).IsEqualTo(1); ((int)obj.a).IsEqualTo(1);
IDictionary<string,object> dict = obj; IDictionary<string,object> dict = obj;
dict.Remove("a"); Assert.Equals(3, dict.Count);
Assert.IsTrue(dict.Remove("a"));
Assert.IsFalse(dict.Remove("d"));
Assert.Equals(2, dict.Count);
dict.Add("d", 4);
Assert.Equals(3, dict.Count);
Assert.Equals("b,c,d", string.Join(",", dict.Keys.OrderBy(x => x)));
Assert.Equals("2,3,4", string.Join(",", dict.OrderBy(x => x.Key).Select(x => x.Value)));
Assert.Equals(2, (int)obj.b);
Assert.Equals(3, (int)obj.c);
Assert.Equals(4, (int)obj.d);
try try
{ {
((int)obj.a).IsEqualTo(1); ((int)obj.a).IsEqualTo(1);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment