/// <summary> /// Return the value of the specified field. /// </summary> /// <param name="i">The index of the field to find.</param> /// <returns> /// The <see cref="T:System.Object" /> which will contain the field value upon return. /// </returns> public virtual object GetValue(int i) { if (i == -1) { return(DBNull.Value); } if (i >= _baseElement.Elements().Count()) { return(DBNull.Value); } var name = GetName(i); var mapEntiysPropToSchema = _target.GetDbToLocalSchemaMapping(name); var firstOrDefault = _target.GetPropertiesEx().FirstOrDefault(s => s.Name == mapEntiysPropToSchema); if (firstOrDefault == null) { return(DBNull.Value); } var propertyType = firstOrDefault.PropertyType; var xElement = _baseElement.Elements().ElementAt(i); if (xElement.HasElements) { return(xElement.ToString()); } var type = DataConverterExtensions.ChangeType(xElement.Value, propertyType); return(type); }
/// <summary> /// Checks the Row version of the local entry and the server on /// </summary> /// <typeparam name="T"></typeparam> /// <returns>True when the version is Equals, otherwise false</returns> private bool CheckRowVersion <T>(T entry) { var type = GetClassInfo(typeof(T)); var rowVersion = GetClassInfo(entry .GetType()) .RowVersionProperty; if (rowVersion != null) { var rowversionValue = rowVersion.GetConvertedValue(entry) as byte[]; if (rowversionValue != null || entry.GetPK(Config) == DataConverterExtensions.GetDefault(type.PrimaryKeyProperty.PropertyType)) { var rowVersionprop = type.GetLocalToDbSchemaMapping(rowVersion.PropertyName); var staticRowVersion = "SELECT " + rowVersionprop + " FROM " + type.TableName + " WHERE " + type.GetPK(Config) + " = " + entry.GetPK(Config); var skalar = Database.GetSkalar(staticRowVersion); if (skalar == null) { return(false); } return(((byte[])skalar).SequenceEqual(rowversionValue)); } return(false); } return(false); }
/// <summary> /// Updates the Entity in memory. Only applies to LocalDbReposetorys that uses Object copys /// </summary> /// <param name="item"></param> /// <returns></returns> public bool Update(TEntity item) { if (item == null) { throw new ArgumentNullException("item"); } TriggersUsage.For.OnUpdate(item); Constraints.Check.Enforce(item); Constraints.Unique.Enforce(item); var getElement = this[GetId(item)]; if (getElement == null) { return(false); } if (ReferenceEquals(item, getElement)) { return(false); } if (!TriggersUsage.InsteadOf.OnUpdate(item)) { DataConverterExtensions.CopyPropertys(item, getElement, _config); } TriggersUsage.After.OnUpdate(item); Constraints.Unique.ItemUpdated(item); return(true); }
/// <summary> /// Sync the Changes to this Collection to the Database /// </summary> public void SaveChanges(DbAccessLayer layer) { var bulk = layer.Database.CreateCommand(""); var removed = new List <T>(); foreach (var pair in _internalCollection) { IDbCommand tempCommand; switch (pair.Value) { case CollectionStates.Added: tempCommand = layer.CreateInsertWithSelectCommand(typeof(T), pair.Key); break; case CollectionStates.Removed: tempCommand = DbAccessLayer.CreateDelete(layer.Database, layer.GetClassInfo(typeof(T)), pair.Key); removed.Add(pair.Key); break; case CollectionStates.Unchanged: tempCommand = null; break; case CollectionStates.Changed: tempCommand = layer.CreateUpdate(pair.Key, layer.Database); break; default: throw new ArgumentOutOfRangeException(); } if (tempCommand != null) { bulk = layer.Database.MergeCommands(bulk, tempCommand, true); } } var results = layer.ExecuteMARS(bulk, typeof(T)).SelectMany(s => s).Cast <T>().ToArray(); //Added var added = _internalCollection.Where(s => s.Value == CollectionStates.Added).ToArray(); for (var i = 0; i < added.Length; i++) { var addedOne = added[i]; var newId = results[i]; DataConverterExtensions.CopyPropertys(addedOne.Value, newId, layer.Config); } //Removed foreach (var item in removed) { _internalCollection.Remove(item); } foreach (var collectionStatese in _internalCollection.Keys.ToArray()) { ChangeState(collectionStatese, CollectionStates.Unchanged); } }
public void TestChangeDateType() { object value = "9999-12-31 23:59:59.9999999+00:00"; Assert.That(DataConverterExtensions.ChangeType(ref value, typeof(DateTimeOffset)), Is.True); Assert.That(value, Is.EqualTo(DateTimeOffset.MaxValue)); }
/// <summary> /// Create a Update statement that will update the entry in the Database /// </summary> /// <param name="database">The database.</param> /// <param name="classInfo">The class information.</param> /// <param name="entry">The entry.</param> /// <returns></returns> /// <exception cref="Exception">No primarykey Provied. An autogenerated Update statement could not be created</exception> public static IDbCommand CreateUpdate(IDatabase database, DbClassInfoCache classInfo, object entry) { var pkProperty = classInfo.PrimaryKeyProperty; if (pkProperty == null) { throw new Exception("No primarykey Provied. An autogenerated Update statement could not be created"); } var pk = classInfo.SchemaMappingLocalToDatabase(pkProperty.PropertyName); var identityInsert = DbIdentityInsertScope.Current != null; var ignore = classInfo .Propertys .Select(f => f.Value) .Where(s => (!identityInsert && s.PrimaryKeyAttribute != null) || s.InsertIgnore || s.UpdateIgnore || s.ForginKeyAttribute != null) .Select(s => s.DbName) .ToArray(); if (identityInsert) { DbIdentityInsertScope.Current.EnableIdentityModfiy(classInfo.TableName, database); } var propertyInfos = classInfo.FilterDbSchemaMapping(ignore).ToArray(); var sb = new StringBuilder(); sb.Append("UPDATE "); sb.Append(classInfo.TableName); sb.Append(" SET "); var para = new List <IQueryParameter>(); for (var index = 0; index < propertyInfos.Length; index++) { var info = propertyInfos[index]; var schemaName = classInfo.GetDbToLocalSchemaMapping(info); DbPropertyInfoCache property; classInfo.Propertys.TryGetValue(schemaName, out property); var dataValue = DataConverterExtensions.GetDataValue(property.GetConvertedValue(entry)); para.Add(new QueryParameter(index.ToString(), dataValue, property.PropertyType)); sb.Append(string.Format(" {0} = @{1} ", info, index)); if (index + 1 < propertyInfos.Length) { sb.Append(","); } } para.Add(new QueryParameter("pkValue", pkProperty.Getter.Invoke(entry), pkProperty.PropertyType)); sb.Append(string.Format("WHERE {0} = @pkValue ", pk)); return(database.CreateCommandWithParameterValues(sb.ToString(), para.ToArray())); }
/// <summary> /// Will update all propertys of entry when /// T contains a Valid RowVersionAttribute property /// AND /// RowVersionAttribute property is not equals the DB version /// OR /// T does not contain any RowVersionAttribute /// </summary> /// <typeparam name="T"></typeparam> /// <returns></returns> public bool RefreshKeepObject <T>(T entry) { //TODO Make async return(Database.RunInTransaction(s => { if (!CheckRowVersion(entry)) { var query = CreateSelect(entry.GetType(), entry.GetPK(Config)); RaiseUpdate(entry, query); var select = RunSelect <T>(query).FirstOrDefault(); return DataConverterExtensions.CopyPropertys(entry, select, Config); } return false; })); }
/// <summary> /// Checks the Row version of the local entry and the server on /// </summary> /// <typeparam name="T"></typeparam> /// <returns>True when the version is Equals, otherwise false</returns> private bool CheckRowVersion <T>(T entry) { var type = GetClassInfo(typeof(T)); var rowVersion = GetClassInfo(entry .GetType()) .RowVersionProperty; if (rowVersion == null) { return(false); } if (type.PrimaryKeyProperty == null) { throw new InvalidOperationException("This Operation requires and Primary Key attribute on the entity to succeed"); } var rowversionValue = rowVersion.GetConvertedValue(entry) as byte[]; if (rowversionValue == null && entry.GetPK(Config) != DataConverterExtensions.GetDefault(type.PrimaryKeyProperty.PropertyType)) { return(false); } var rowVersionprop = type.GetLocalToDbSchemaMapping(rowVersion.PropertyName); var staticRowVersion = "SELECT " + rowVersionprop + " FROM " + type.TableName + " WHERE " + type.PrimaryKeyProperty.DbName + " = " + entry.GetPK(Config); #pragma warning disable 618 var skalar = Database.GetSkalar(staticRowVersion); #pragma warning restore 618 if (skalar == null) { return(false); } return(((byte[])skalar).SequenceEqual(rowversionValue)); }
/// <summary> /// Create a Update statement that will update the entry in the Database /// </summary> /// <param name="database">The database.</param> /// <param name="classInfo">The class information.</param> /// <param name="entry">The entry.</param> /// <returns></returns> /// <exception cref="Exception">No primarykey Provied. An autogenerated Update statement could not be created</exception> public static IDbCommand CreateUpdateSimple(IDatabase database, DbClassInfoCache classInfo, object entry) { var ignore = classInfo .Propertys .Select(f => f.Value) .Where(s => s.PrimaryKeyAttribute != null || s.InsertIgnore || s.UpdateIgnore || s.ForginKeyAttribute != null) .Select(s => s.DbName) .ToArray(); var propertyInfos = classInfo.FilterDbSchemaMapping(ignore).ToArray(); var sb = new StringBuilder(); sb.Append("UPDATE "); sb.Append(classInfo.TableName); sb.Append(" SET "); var para = new List <IQueryParameter>(); for (var index = 0; index < propertyInfos.Length; index++) { var info = propertyInfos[index]; var schemaName = classInfo.GetDbToLocalSchemaMapping(info); DbPropertyInfoCache property; classInfo.Propertys.TryGetValue(schemaName, out property); var dataValue = DataConverterExtensions.GetDataValue(property.GetConvertedValue(entry)); para.Add(new QueryParameter(index.ToString(), dataValue, property.PropertyType)); sb.Append(string.Format(" {0} = @{1} ", info, index)); if (index + 1 < propertyInfos.Length) { sb.Append(","); } } return(database.CreateCommandWithParameterValues(sb.ToString(), para.ToArray())); }
public static object ReflectionPropertySet( DbConfig config, object instance, DbClassInfoCache info, IDataRecord reader, Dictionary <int, DbPropertyInfoCache> cache, DbAccessType?dbAccessType) { if (instance == null) { throw new ArgumentNullException("instance"); } if (info == null) { throw new ArgumentNullException("info"); } if (reader == null) { return(instance); } //Left c# property name and right the object to read from the reader //var listofpropertys = new Dictionary<string, object>(); var propertys = info.Propertys.ToArray(); var instanceOfFallbackList = new Dictionary <string, object>(); if (cache == null) { cache = new Dictionary <int, DbPropertyInfoCache>(); for (var i = 0; i < reader.FieldCount; i++) { DbPropertyInfoCache val = null; info.Propertys.TryGetValue(info.SchemaMappingDatabaseToLocal(reader.GetName(i)), out val); cache.Add(i, val); } } for (var i = 0; i < reader.FieldCount; i++) { var property = cache[i]; var value = reader.GetValue(i); if (property != null) { var attributes = property.Attributes; var valueConverterAttributeModel = attributes.FirstOrDefault(s => s.Attribute is ValueConverterAttribute); //Should the SQL value be converted if (valueConverterAttributeModel != null) { var converter = valueConverterAttributeModel.Attribute as ValueConverterAttribute; //Create the converter and then convert the value before everything else var valueConverter = converter.CreateConverter(); value = valueConverter.Convert(value, property.PropertyInfo.PropertyType, converter.Parameter, CultureInfo.CurrentCulture); } var xmlAttributeModel = attributes.FirstOrDefault(s => s.Attribute is FromXmlAttribute); //should the Content be considerd as XML text? if (xmlAttributeModel != null) { //Get the XML text and check if its null or empty var xmlStream = value.ToString(); if (string.IsNullOrEmpty(xmlStream)) { continue; } //Check for List //if this is a list we are expecting other entrys inside if (property.CheckForListInterface()) { //target Property is of type list //so expect a xml valid list Take the first element and expect the propertys inside this first element var record = XmlDataRecord.TryParse(xmlStream, property.PropertyInfo.PropertyType.GetGenericArguments().FirstOrDefault(), false, config); var xmlDataRecords = record.CreateListOfItems(); var genericArguments = config.GetOrCreateClassInfoCache( property.PropertyInfo.PropertyType.GetGenericArguments().FirstOrDefault()); var enumerableOfItems = xmlDataRecords.Select( s => genericArguments.SetPropertysViaReflection(s, dbAccessType, config)).ToList(); object castedList; if (genericArguments.Type.IsClass && genericArguments.Type.GetInterface("INotifyPropertyChanged") != null) { var caster = typeof(DbCollection <>).MakeGenericType(genericArguments.Type) .GetConstructor(new[] { typeof(IEnumerable) }); castedList = caster.Invoke(new object[] { enumerableOfItems }); } else { var caster = typeof(NonObservableDbCollection <>).MakeGenericType(genericArguments.Type) .GetConstructor(new[] { typeof(IEnumerable) }); castedList = caster.Invoke(new object[] { enumerableOfItems }); } property.Setter.Invoke(instance, castedList); } else { var classInfo = config.GetOrCreateClassInfoCache(property .PropertyInfo .PropertyType); var xmlDataRecord = XmlDataRecord.TryParse(xmlStream, property.PropertyInfo.PropertyType, true, config); //the t var xmlSerilizedProperty = classInfo.SetPropertysViaReflection(xmlDataRecord, dbAccessType, config); property.Setter.Invoke(instance, xmlSerilizedProperty); } } else if (value is DBNull || value == null) { property.Setter.Invoke(instance, new object[] { null }); } else { object changedType; if (value.GetType() != property.PropertyInfo.PropertyType) { changedType = DataConverterExtensions.ChangeType(value, property.PropertyInfo.PropertyType); } else { changedType = value; } property.Setter.Invoke(instance, changedType); } } //This variable is null if we tried to find a property with the LoadNotImplimentedDynamicAttribute but did not found it else if (instanceOfFallbackList != null) { //no property found Look for LoadNotImplimentedDynamicAttribute property to include it if (instanceOfFallbackList.Any()) { instanceOfFallbackList.Add(reader.GetName(i), value); } else { var maybeFallbackProperty = propertys.FirstOrDefault( s => s.Value.Attributes.Any(e => e.Attribute is LoadNotImplimentedDynamicAttribute)); if (maybeFallbackProperty.Value != null) { instanceOfFallbackList = (Dictionary <string, object>)maybeFallbackProperty.Value.Getter.Invoke(instance); if (instanceOfFallbackList == null) { instanceOfFallbackList = new Dictionary <string, object>(); maybeFallbackProperty.Value.Setter.Invoke(instance, instanceOfFallbackList); } instanceOfFallbackList.Add(reader.GetName(i), value); } else { instanceOfFallbackList = null; } } } } //foreach (var item in listofpropertys) //{ // var property = propertys.FirstOrDefault(s => s.PropertyName == item.Key); //} return(instance); }
/// <summary> /// Reads the XML. /// </summary> /// <param name="reader">The reader.</param> /// <exception cref="InvalidDataException"> /// Invalid XML document for Db import. index is unset /// or /// Invalid XML document for Db import. type is unset /// or /// or /// Invalid XML document for Db import. index for a table is unset /// </exception> public void ReadXml(XmlReader reader) { reader.Read(); reader.ReadStartElement(DatabaseName); reader.ReadStartElement(ReprosIncluded); var elements = new Dictionary <string, Type>(); do { var indexOfElementString = reader.GetAttribute("Index"); var typeString = reader.GetAttribute("Type"); if (indexOfElementString == null) { throw new InvalidDataException("Invalid XML document for Db import. index is unset"); } if (typeString == null) { throw new InvalidDataException("Invalid XML document for Db import. type is unset"); } var type = Type.GetType(typeString); if (type == null) { throw new InvalidDataException(string.Format("Invalid XML document for Db import. type is invalid '{0}'", typeString)); } elements.Add(indexOfElementString, type); } while (reader.Read() && reader.Name == ReproIncluded); reader.ReadEndElement(); reader.ReadStartElement(DatabaseContent); using (var transaction = new TransactionScope()) { using (DbReposetoryIdentityInsertScope.CreateOrObtain()) { do { var indexOfElementString = reader.GetAttribute("Index"); if (indexOfElementString == null) { throw new InvalidDataException("Invalid XML document for Db import. index for a table is unset"); } reader.ReadStartElement(TableContentList); var type = elements[indexOfElementString]; var table = LocalDbManager.Scope.Database.First(s => s.Key.AssemblyQualifiedName == type.AssemblyQualifiedName).Value; if (table == null) { throw new InvalidDataException("Invalid Database config for Db import. There is no Table for the type " + type); } reader.ReadStartElement(TableContentElementsList); do { object emptyElement = table.TypeInfo.DefaultFactory(); reader.ReadStartElement(table.TypeInfo.TableName); do { var propName = reader.Name; var isNumm = reader.IsEmptyElement; var value = reader.ReadElementContentAsString(); var dbPropertyInfoCache = table.TypeInfo.Propertys[table.TypeInfo.SchemaMappingDatabaseToLocal(propName)]; object contvertedValue = null; if (!isNumm) { contvertedValue = DataConverterExtensions.ChangeType(value, dbPropertyInfoCache.PropertyType); } dbPropertyInfoCache.Setter.Invoke(emptyElement, contvertedValue); } while (reader.Name != table.TypeInfo.TableName); reader.ReadEndElement(); table.Add(emptyElement); } while (reader.Name == table.TypeInfo.TableName); reader.ReadEndElement(); //for newer indexer tags. Currently unsupported if (reader.Name == IndexerIncluded) { reader.ReadStartElement(IndexerIncluded); reader.ReadEndElement(); } } while (reader.Name != DatabaseContent); transaction.Complete(); } } }
public void TestChangeDateType() { Assert.That(() => DataConverterExtensions.ChangeType("9999-12-31 23:59:59.9999999+00:00", typeof(DateTimeOffset)), Is.EqualTo(DateTimeOffset.MaxValue)); }
//[TestCase("12/31/99 23:59:59 +00:00", typeof(DateTimeOffset), DateTimeOffset.MaxValue)] public void TestChangeType(object input, Type toType, object expected) { Assert.That(() => DataConverterExtensions.ChangeType(input, toType), Is.EqualTo(expected)); }