예제 #1
0
        /// <summary>
        /// Constructor for an EntityContext object that uses the <see cref="ReflectionMappingProvider"/>
        /// to populate its entity type and property mappings.
        /// </summary>
        /// <remarks>This method is provided so that classes derived from <see cref="EntityContext"/>
        /// can be defined with additional properties that provide access to the types of entities that the context manages</remarks>
        protected EntityContext()
        {
            Mappings = new EntityMappingStore();
            var rmp = new ReflectionMappingProvider();

            rmp.AddMappingsForContext(Mappings, this);
        }
예제 #2
0
        /// <summary>
        /// Attaches the object to the specified context
        /// </summary>
        /// <param name="context"></param>
        /// <param name="overwriteExisting"></param>
        public void Attach(EntityContext context, bool overwriteExisting = false)
        {
            if (context == null)
            {
                throw new ArgumentNullException("context");
            }
            if (!(context is BrightstarEntityContext))
            {
                throw new ArgumentException(
                          String.Format("An object of type {0} can only be attached to a context that extends {1}",
                                        GetType().FullName, typeof(BrightstarEntityContext).FullName));
            }
            if (IsAttached)
            {
                if (!context.Equals(_context))
                {
                    _context.UntrackObject(this);
                }
            }
            _context = context as BrightstarEntityContext;
            if (_identity == null)
            {
                AssertIdentity();
            }
            if (DataObject == null && _identity != null)
            {
                DataObject = _context.GetDataObject(new Uri(_identity), false);
                var identityInfo = EntityMappingStore.GetIdentityInfo(GetType());
                if (identityInfo != null && identityInfo.EnforceClassUniqueConstraint && !overwriteExisting)
                {
                    _context.EnforceClassUniqueConstraint(_identity, EntityMappingStore.MapTypeToUris(GetType()));
                }
                foreach (var typeUri in EntityMappingStore.MapTypeToUris(GetType()))
                {
                    if (!String.IsNullOrEmpty(typeUri))
                    {
                        var typeDo = _context.GetDataObject(new Uri(typeUri), false);
                        if (typeDo != null)
                        {
                            DataObject.AddProperty(Client.DataObject.TypeDataObject, typeDo);
                        }
                    }
                }
            }
//            if (DataObject != null)
//            {
            _context.TrackObject(this);
//            }

            if (_currentItemValues != null)
            {
                foreach (var propertyName in _currentItemValues.Keys.ToList())
                {
                    PropertyInfo p = GetType().GetProperty(propertyName);
                    p.SetValue(this, _currentItemValues[propertyName], null);
                }
                _currentItemValues.Clear();
            }
        }
        /// <summary>
        /// Creates a new domain context
        /// </summary>
        /// <param name="mappings">The context type and property mappings</param>
        ///<param name="connectionString">The connection string that will be used to connect to an existing BrightstarDB store</param>
        ///<param name="enableOptimisticLocking">Optional parameter to override the optimistic locking configuration specified in the connection string</param>
        public BrightstarEntityContext(EntityMappingStore mappings, string connectionString, bool?enableOptimisticLocking = null) : base(mappings)
        {
            var cstr = new ConnectionString(connectionString);

            AssertStoreFromConnectionString(cstr);
            _store          = OpenStore(cstr, enableOptimisticLocking);
            _trackedObjects = new Dictionary <string, List <BrightstarEntityObject> >();
        }
예제 #4
0
 /// <summary>
 /// Creates a new mapping store that copies its initial mappings from the specified source store
 /// </summary>
 /// <param name="source">The source <see cref="EntityMappingStore"/> from which mappings are copied</param>
 public EntityMappingStore(EntityMappingStore source)
 {
     _typeMappings       = new Dictionary <Type, string>(source._typeMappings);
     _identifierPrefixes = new Dictionary <Type, string>(source._identifierPrefixes);
     _propertyHints      = new Dictionary <PropertyInfo, PropertyHint>(source._propertyHints);
     _implMappings       = new Dictionary <Type, Type>(source._implMappings);
     _identityProperties = new Dictionary <Type, PropertyInfo>(source._identityProperties);
 }
        /// <summary>
        /// Creates a new domain context and connects to the store specified in the configuration connectionString.
        /// </summary>
        /// <param name="mappings">The context type and property mappings</param>
        public BrightstarEntityContext(EntityMappingStore mappings)
            : base(mappings)
        {
            var cstr = new ConnectionString(Configuration.ConnectionString);

            AssertStoreFromConnectionString(cstr);
            _store          = OpenStore(cstr);
            _trackedObjects = new Dictionary <string, List <BrightstarEntityObject> >();
        }
예제 #6
0
        /// <summary>
        /// Creates a new domain context
        /// </summary>
        /// <param name="mappings">The context type and property mappings</param>
        ///<param name="connectionString">The connection string that will be used to connect to an existing BrightstarDB store</param>
        ///<param name="enableOptimisticLocking">Optional parameter to override the optimistic locking configuration specified in the connection string</param>
        /// <param name="updateGraphUri">OPTIONAL: The URI identifier of the graph to be updated with any new triples created by operations on the store. If
        /// not defined, the default graph in the store will be updated.</param>
        /// <param name="datasetGraphUris">OPTIONAL: The URI identifiers of the graphs that will be queried to retrieve entities and their properties. See
        /// the remarks below.</param>
        /// <param name="versionGraphUri">OPTIONAL: The URI identifier of the graph that contains version number statements for entities.
        /// If not defined, the <paramref name="updateGraphUri"/> will be used.</param>
        /// <remarks>
        /// <para>If <paramref name="datasetGraphUris"/> is null, then the context will query the graphs defined by
        /// <paramref name="updateGraphUri"/> and <paramref name="versionGraphUri"/> only. If all three parameters
        /// are null then the context will query across all graphs in the store.</para>
        /// </remarks>
        protected BrightstarEntityContext(EntityMappingStore mappings, string connectionString, bool?enableOptimisticLocking = null,
                                          string updateGraphUri = null, IEnumerable <string> datasetGraphUris = null, string versionGraphUri = null) : base(mappings)
        {
            var cstr = new ConnectionString(connectionString);

            AssertStoreFromConnectionString(cstr);
            _store = OpenStore(cstr, enableOptimisticLocking,
                               updateGraphUri, datasetGraphUris, versionGraphUri);
            _trackedObjects = new Dictionary <string, List <BrightstarEntityObject> >();
        }
예제 #7
0
 /// <summary>
 /// Returns the RDF schema type for the specified entity interface or implementation type
 /// </summary>
 /// <param name="type">The entity interface or implementation type</param>
 /// <returns>The schema type URI for the entity type</returns>
 /// <exception cref="MappingNotFoundException">Raised if no mapping is found for <paramref name="type"/></exception>
 public string MapTypeToUri(Type type)
 {
     if (EntityMappingStore.IsMappedImplementation(type))
     {
         return(EntityMappingStore.GetMappedInterfaceTypeUri(type));
     }
     if (EntityMappingStore.IsKnownInterface(type))
     {
         return(EntityMappingStore.GetMappedInterfaceTypeUri(EntityMappingStore.GetImplType(type)));
     }
     throw new MappingNotFoundException(type);
 }
        /// <summary>
        /// Populates a <see cref="EntityMappingStore"/> with the entity mapping and property mapping information
        /// found on an entity implementation type
        /// </summary>
        /// <param name="mappingStore">The <see cref="EntityMappingStore"/> to be updated</param>
        /// <param name="mappedType">The entity implementation type to be processed</param>
        public void AddMappingsForType(EntityMappingStore mappingStore, Type mappedType)
        {
            var mappedTypeAssembly = mappedType.Assembly;
            AssemblyMappingInfo assemblyMappings;

            if (!_assemblyMappings.TryGetValue(mappedTypeAssembly.FullName, out assemblyMappings))
            {
                assemblyMappings = GetAssemblyMappingInfo(mappedTypeAssembly);
                _assemblyMappings[mappedTypeAssembly.FullName] = assemblyMappings;
            }
            AddMappingsForType(mappingStore, assemblyMappings, mappedType);
        }
        /// <summary>
        /// Processes the specified assembly for entity implementation types and adds all mapping information
        /// to the specified mapping store
        /// </summary>
        /// <param name="mappingStore">The <see cref="EntityMappingStore"/> to be updated</param>
        /// <param name="assembly">The assembly to be processed</param>
        public void AddMappingsForAssembly(EntityMappingStore mappingStore, Assembly assembly)
        {
            AssemblyMappingInfo assemblyMappings;

            if (!_assemblyMappings.TryGetValue(assembly.FullName, out assemblyMappings))
            {
                assemblyMappings = GetAssemblyMappingInfo(assembly);
                _assemblyMappings[assembly.FullName] = assemblyMappings;
            }
            foreach (var t in assembly.GetTypes())
            {
                AddMappingsForType(mappingStore, assemblyMappings, t);
            }
        }
예제 #10
0
        /// <summary>
        /// Raises the PropertyChanged event
        /// </summary>
        /// <param name="propertyName">The name of the property that has been modified</param>
        protected virtual void OnPropertyChanged(string propertyName)
        {
            var identityInfo = EntityMappingStore.GetIdentityInfo(GetType());

            if (identityInfo != null && identityInfo.KeyProperties != null && identityInfo.KeyProperties.Any(p => p.Name.Equals(propertyName)))
            {
                var newKey = GenerateEntityKey();
                SetKey(newKey);
            }

            PropertyChangedEventHandler handler = PropertyChanged;

            if (handler != null)
            {
                handler(this, new PropertyChangedEventArgs(propertyName));
            }
        }
예제 #11
0
        private string GenerateEntityKey()
        {
            var identityCacheInfo = EntityMappingStore.GetIdentityInfo(GetType());

            if (identityCacheInfo != null && identityCacheInfo.KeyProperties != null)
            {
                // Generate the key string
                var values = new object[identityCacheInfo.KeyProperties.Length];
                for (var i = 0; i < identityCacheInfo.KeyProperties.Length; i++)
                {
                    if (!_currentItemValues.TryGetValue(identityCacheInfo.KeyProperties[i].Name, out values[i]))
                    {
                        values[i] = identityCacheInfo.KeyProperties[i].GetValue(this, null);
                    }
                }
                return(identityCacheInfo.KeyConverter.GenerateKey(values, identityCacheInfo.KeySeparator, GetType()));
            }
            return(Guid.NewGuid().ToString());
        }
        /// <summary>
        /// Processes a <see cref="EntityContext"/> instance to extract mapping details and uses them to populate
        /// a <see cref="EntityMappingStore"/>
        /// </summary>
        /// <param name="mappingStore">The <see cref="EntityMappingStore"/> to be populated</param>
        /// <param name="context">The <see cref="EntityContext"/> to be processed</param>
        public void AddMappingsForContext(EntityMappingStore mappingStore, EntityContext context)
        {
            var contextType     = context.GetType();
            var contextAssembly = contextType.Assembly;
            AssemblyMappingInfo assemblyMappings;

            if (!_assemblyMappings.TryGetValue(contextAssembly.FullName, out assemblyMappings))
            {
                assemblyMappings = GetAssemblyMappingInfo(contextAssembly);
                _assemblyMappings[contextAssembly.FullName] = assemblyMappings;
            }
            var queryableGeneric = typeof(IQueryable <object>).GetGenericTypeDefinition();

            foreach (var p in contextType.GetProperties())
            {
                if (p.PropertyType.IsGenericType &&
                    queryableGeneric.IsAssignableFrom(p.PropertyType.GetGenericTypeDefinition()))
                {
                    var genericParam = p.PropertyType.GetGenericArguments()[0];
                    AddMappingsForType(mappingStore, genericParam);
                }
            }
        }
예제 #13
0
 /// <summary>
 /// Returns true if <paramref name="o"/> is an instance of one of the entity implementation types known to this context
 /// </summary>
 /// <param name="o">The object to be checked</param>
 /// <returns>True if the object is an instance of a known entity implementation type, false otherwise</returns>
 public bool IsOfMappedType(object o)
 {
     return(EntityMappingStore.IsKnownInterface(o.GetType()) || EntityMappingStore.IsMappedImplementation(o.GetType()));
 }
예제 #14
0
 /// <summary>
 /// Returns the entity implementation type for an entity interface type
 /// </summary>
 /// <param name="interfaceType">The entity interface type</param>
 /// <returns>The mapped entity implementation type, or <paramref name="interfaceType"/> if no mapping is found</returns>
 public Type GetImplType(Type interfaceType)
 {
     return(EntityMappingStore.GetImplType(interfaceType));
 }
예제 #15
0
 /// <summary>
 /// Constructor for an EntityContext object
 /// </summary>
 /// <param name="mappings">The store providing type and property mappings to use in LINQ to SPARQL queries</param>
 protected EntityContext(EntityMappingStore mappings)
 {
     Mappings = mappings;
 }
예제 #16
0
 /// <summary>
 /// Creates a new domain context
 /// </summary>
 /// <param name="mappings">The context type and property mappings</param>
 /// <param name="store">The Brightstar store that manages the data</param>
 protected BrightstarEntityContext(EntityMappingStore mappings, IDataObjectStore store) : base(mappings)
 {
     _store          = store;
     _trackedObjects = new Dictionary <string, List <BrightstarEntityObject> >();
 }
예제 #17
0
        internal string GetIdentityBase()
        {
            var identityCacheInfo = EntityMappingStore.GetIdentityInfo(GetType());

            return(identityCacheInfo.BaseUri);
        }
        private static void AddMappingsForType(EntityMappingStore mappingStore, AssemblyMappingInfo assemblyMappingInfo, Type mappedType)
        {
            var entityAttribute =
                mappedType.GetCustomAttributes(typeof(EntityAttribute), false).OfType <EntityAttribute>().
                FirstOrDefault();

            if (entityAttribute != null)
            {
                var entityTypeIdentifier = entityAttribute.Identifier ?? GetImplTypeName(mappedType);

                mappingStore.SetTypeMapping(mappedType, assemblyMappingInfo.ResolveIdentifier(entityTypeIdentifier));
                var identityProperty = GetIdentityProperty(mappedType);
                if (identityProperty != null)
                {
                    var identifierAttr =
                        identityProperty.GetCustomAttributes(typeof(IdentifierAttribute), true).Cast
                        <IdentifierAttribute>().FirstOrDefault();
                    var identityInfo = GetIdentityInfo(assemblyMappingInfo, mappedType, identityProperty, identifierAttr);
                    mappingStore.SetIdentityInfo(mappedType, identityInfo);
                    mappingStore.SetPropertyHint(identityProperty, new PropertyHint(PropertyMappingType.Id));
                }

                foreach (var p in mappedType.GetProperties())
                {
                    if (p.Equals(identityProperty))
                    {
                        // Identity property is already mapped (above)
                        continue;
                    }

                    foreach (var attr in p.GetCustomAttributes(false))
                    {
                        /*
                         * if (attr is IdentifierAttribute)
                         * {
                         *  mappingStore.SetPropertyHint(p, new PropertyHint(PropertyMappingType.Address));
                         *  var idAttr = attr as IdentifierAttribute;
                         *  if (idAttr.BaseAddress != null)
                         *  {
                         *      mappingStore.SetIdentifierPrefix(mappedType, assemblyMappingInfo.ResolveIdentifier(idAttr.BaseAddress));
                         *  }
                         * }
                         * else*/
                        if (attr is PropertyTypeAttribute)
                        {
                            var propertyUri =
                                assemblyMappingInfo.ResolveIdentifier((attr as PropertyTypeAttribute).Identifier);
                            mappingStore.SetPropertyHint(p,
                                                         IsResource(p.PropertyType)
                                                             ? new PropertyHint(PropertyMappingType.Arc, propertyUri)
                                                             : new PropertyHint(PropertyMappingType.Property,
                                                                                propertyUri));
                        }
                        else if (attr is InversePropertyTypeAttribute)
                        {
                            var propertyUri =
                                assemblyMappingInfo.ResolveIdentifier((attr as InversePropertyTypeAttribute).Identifier);
                            var targetType = p.PropertyType;
                            if (targetType.IsGenericType)
                            {
                                targetType = targetType.GetGenericArguments().First();
                            }
                            if (targetType.GetCustomAttributes(typeof(EntityAttribute), false).Any())
                            {
                                mappingStore.SetPropertyHint(p,
                                                             new PropertyHint(PropertyMappingType.InverseArc,
                                                                              propertyUri));
                            }
                            else
                            {
                                throw new ReflectionMappingException(
                                          String.Format(
                                              "The property '{0}' on type '{1}' is marked with the InverseProperty attribute but its referenced type ('{2}') is not marked with a Entity attribute.",
                                              p.Name, mappedType.FullName, p.PropertyType.FullName));
                            }
                        }
                        else if (attr is InversePropertyAttribute)
                        {
                            var inversePropertyAttr = attr as InversePropertyAttribute;
                            var targetType          = p.PropertyType;
                            if (targetType.IsGenericType)
                            {
                                targetType = targetType.GetGenericArguments().First();
                            }
                            if (!targetType.GetCustomAttributes(typeof(EntityAttribute), true).Any())
                            {
                                throw new ReflectionMappingException(
                                          String.Format(
                                              "The type of property '{0}' on interface '{1}' is not marked with an Entity attribute.",
                                              p.Name, mappedType.FullName));
                            }
                            var forwardProperty = targetType.GetProperty(inversePropertyAttr.InversePropertyName);
                            if (forwardProperty == null)
                            {
                                throw new ReflectionMappingException(String.Format("The property '{0}' does not exist on type '{1}'.", inversePropertyAttr.InversePropertyName, targetType.FullName));
                            }
                            var inversePropertyTypeUri =
                                assemblyMappingInfo.ResolveIdentifier(GetForwardPropertyTypeUri(forwardProperty, p));
                            mappingStore.SetPropertyHint(p, new PropertyHint(PropertyMappingType.InverseArc, inversePropertyTypeUri));
                        }
                    }
                    if (mappingStore.GetPropertyHint(p) == null)
                    {
                        // If there has been no mapping at all, then we create a property mapping
                        var propertyName = Char.ToLowerInvariant(p.Name[0]) + p.Name.Substring(1);
                        var propertyUri  = assemblyMappingInfo.ResolveIdentifier(propertyName);

                        mappingStore.SetPropertyHint(p,
                                                     IsResource(p.PropertyType) ?
                                                     new PropertyHint(PropertyMappingType.Arc, propertyUri) :
                                                     new PropertyHint(PropertyMappingType.Property, propertyUri));
                    }
                }
            }
        }