private static PropertyContainer ParseProperties <T>(T obj) { PropertyContainer propertyContainer = new PropertyContainer(); IEnumerable <PropertyInfo> properties = typeof(T).GetProperties().Where(c => c.DeclaringType == typeof(T) || c.IsDefined(typeof(DapperKeyAttribute), false)); foreach (PropertyInfo property in properties) { // Skip reference types (but still include string!) if (property.PropertyType.GetTypeInfo().IsInterface || (property.PropertyType.GetTypeInfo().IsClass&& property.PropertyType != typeof(string))) { continue; } // Skip methods without a public setter if (property.GetSetMethod() == null) { continue; } // Skip methods without db type defined if (!property.IsDefined(typeof(DapperTypeAttribute), false)) { continue; } object value = typeof(T).GetProperty(property.Name).GetValue(obj, null); DbType dbType = ((DapperTypeAttribute)property.GetCustomAttribute(typeof(DapperTypeAttribute))).DbType; bool isKey = property.IsDefined(typeof(DapperKeyAttribute), false); bool isCriticalCommand = property.IsDefined(typeof(DapperCriticalRestrictionAttribute), false); if (isKey && isCriticalCommand) { throw new InvalidOperationException("Critical restriction cannot be set on Key."); } if (isKey) { propertyContainer.AddKey(property.Name, value, dbType, ((DapperKeyAttribute)property.GetCustomAttribute(typeof(DapperKeyAttribute))).Identity); } else { propertyContainer.AddValue(property.Name, value, dbType, isCriticalCommand); } if (isCriticalCommand) { propertyContainer.AddCriticalRestriction(property.Name, ((DapperCriticalRestrictionAttribute)property.GetCustomAttribute(typeof(DapperCriticalRestrictionAttribute))).SqlOperation); } } return(propertyContainer); }