diff --git a/FastMember/ObjectReader.cs b/FastMember/ObjectReader.cs index 61e9e96..287a1f4 100644 --- a/FastMember/ObjectReader.cs +++ b/FastMember/ObjectReader.cs @@ -4,6 +4,8 @@ using System.Data; using System.Data.Common; using System.Linq; +using System.Linq.Expressions; +using System.Reflection; namespace FastMember { @@ -18,6 +20,25 @@ public class ObjectReader : DbDataReader private readonly string[] memberNames; private readonly Type[] effectiveTypes; private readonly BitArray allowNull; + private readonly string keyPropertyName; + + /// + /// Creates a new ObjectReader instance for reading the supplied data + /// + /// The sequence of objects to represent + /// Current object property expression to set IsKey column value for schema table + /// The members that should be exposed to the reader + public static ObjectReader Create(IEnumerable source, Expression> keyPropertyExpression, params string[] members) + { + if(keyPropertyExpression == null) throw new ArgumentNullException(nameof(keyPropertyExpression)); + + var memberExpression = keyPropertyExpression.Body as MemberExpression + ?? throw new ArgumentException("Expression is not valid"); + + var keyPropertyMemberInfo = memberExpression.Member; + + return new ObjectReader(typeof(TSource), source, keyPropertyMemberInfo, members); + } /// /// Creates a new ObjectReader instance for reading the supplied data @@ -34,12 +55,25 @@ public static ObjectReader Create(IEnumerable source, params string[] memb /// /// The expected Type of the information to be read /// The sequence of objects to represent + /// Current object property info to set IsKey column value for schema table /// The members that should be exposed to the reader - public ObjectReader(Type type, IEnumerable source, params string[] members) + public ObjectReader(Type type, IEnumerable source, MemberInfo keyPropertyMemberInfo, params string[] members) : + this(type, source, members) { - if (source == null) throw new ArgumentOutOfRangeException("source"); - + if (keyPropertyMemberInfo == null) throw new ArgumentNullException(nameof(keyPropertyMemberInfo)); + this.keyPropertyName = keyPropertyMemberInfo.Name; + } + + /// + /// Creates a new ObjectReader instance for reading the supplied data + /// + /// The expected Type of the information to be read + /// The sequence of objects to represent + /// The members that should be exposed to the reader + public ObjectReader(Type type, IEnumerable source, params string[] members) + { + if (source == null) throw new ArgumentOutOfRangeException(nameof(source)); bool allMembers = members == null || members.Length == 0; @@ -119,17 +153,21 @@ public override DataTable GetSchemaTable() {"ColumnName", typeof(string)}, {"DataType", typeof(Type)}, {"ColumnSize", typeof(int)}, - {"AllowDBNull", typeof(bool)} + {"AllowDBNull", typeof(bool)}, + {"IsKey", typeof(bool)} } }; object[] rowData = new object[5]; for (int i = 0; i < memberNames.Length; i++) { + var memberName = memberNames[i]; + rowData[0] = i; - rowData[1] = memberNames[i]; + rowData[1] = memberName; rowData[2] = effectiveTypes == null ? typeof(object) : effectiveTypes[i]; rowData[3] = -1; rowData[4] = allowNull == null ? true : allowNull[i]; + rowData[5] = memberName == keyPropertyName; table.Rows.Add(rowData); } return table; @@ -147,6 +185,7 @@ public override bool HasRows } } private bool active = true; + public override bool NextResult() { active = false;