EntitySet.cs :  » Content-Management-Systems-CMS » Kooboo » Microsoft » Data » Extensions » C# / CSharp Open Source

Home
C# / CSharp Open Source
1.2.6.4 mono .net core
2.2.6.4 mono core
3.Aspect Oriented Frameworks
4.Bloggers
5.Build Systems
6.Business Application
7.Charting Reporting Tools
8.Chat Servers
9.Code Coverage Tools
10.Content Management Systems CMS
11.CRM ERP
12.Database
13.Development
14.Email
15.Forum
16.Game
17.GIS
18.GUI
19.IDEs
20.Installers Generators
21.Inversion of Control Dependency Injection
22.Issue Tracking
23.Logging Tools
24.Message
25.Mobile
26.Network Clients
27.Network Servers
28.Office
29.PDF
30.Persistence Frameworks
31.Portals
32.Profilers
33.Project Management
34.RSS RDF
35.Rule Engines
36.Script
37.Search Engines
38.Sound Audio
39.Source Control
40.SQL Clients
41.Template Engines
42.Testing
43.UML
44.Web Frameworks
45.Web Service
46.Web Testing
47.Wiki Engines
48.Windows Presentation Foundation
49.Workflows
50.XML Parsers
C# / C Sharp
C# / C Sharp by API
C# / CSharp Tutorial
C# / CSharp Open Source » Content Management Systems CMS » Kooboo 
Kooboo » Microsoft » Data » Extensions » EntitySet.cs
/*
Kooboo is a content management system based on ASP.NET MVC framework. Copyright 2009 Yardi Technology Limited.

This program is free software: you can redistribute it and/or modify it under the terms of the
GNU General Public License version 3 as published by the Free Software Foundation.

This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with this program.
If not, see http://www.kooboo.com/gpl3/.
*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.Objects;
using System.Data.Metadata.Edm;
using System.Data.Objects.DataClasses;
using System.Data;
using System.Globalization;

namespace Microsoft.Data.Extensions{
    /// <summary>
    /// Provides an alternate entry point for Entity Framework queries. Supports querying and modifying/observing
    /// state for an EDM EntitySet.
    /// </summary>
    /// <typeparam name="T">Element type for the entity set.</typeparam>
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Naming", "CA1710:IdentifiersShouldHaveCorrectSuffix")]
    public class EntitySet<T> : ObjectQuery<T> {
        private readonly EntitySet metadata;

        /// <summary>
        /// Constructs an entity set query.
        /// </summary>
        /// <param name="context">Context to which entity set is bound.</param>
        public EntitySet(ObjectContext context)
            : this(context, (string)null, (string)null, MergeOption.AppendOnly) { }

        /// <summary>
        /// Construct an entity set query.
        /// </summary>
        /// <param name="context">Context to which entity set is bound.</param>
        /// <param name="entitySetName">Name of the entity set. Must be consistent with the
        /// entity set element type.</param>
        public EntitySet(ObjectContext context, string entitySetName)
            : this(context, (string)null, entitySetName, MergeOption.AppendOnly) { }

        /// <summary>
        /// Construct an entity set query.
        /// </summary>
        /// <param name="context">Context to which entity set is bound.</param>
        /// <param name="entitySetName">Name of the entity set. Must be consistent with the
        /// entity set element type.</param>
        /// <param name="mergeOption">Merge option to use for the query.</param>
        public EntitySet(ObjectContext context, string entitySetName, MergeOption mergeOption)
            : this(context, (string)null, entitySetName, mergeOption) { }

        /// <summary>
        /// Construct an entity set query.
        /// </summary>
        /// <param name="context">Context to which entity set is bound.</param>
        /// <param name="containerName">Name of the entity set's container.</param>
        /// <param name="entitySetName">Name of the entity set. Must be consistent with the
        /// entity set element type.</param>
        public EntitySet(ObjectContext context, string containerName, string entitySetName)
            : this(context, containerName, entitySetName, MergeOption.AppendOnly) { }

        /// <summary>
        /// Construct an entity set query.
        /// </summary>
        /// <param name="context">Context to which entity set is bound.</param>
        /// <param name="containerName">Name of the entity set's container.</param>
        /// <param name="entitySetName">Name of the entity set. Must be consistent with the
        /// entity set element type.</param>
        /// <param name="mergeOption">Merge option to use for the query.</param>
        public EntitySet(ObjectContext context, string containerName, string entitySetName, MergeOption mergeOption)
            : this(context, GetEntitySet(context, containerName, entitySetName), mergeOption) { }

        private EntitySet(ObjectContext context, EntitySet entitySet, MergeOption mergeOption)
            : base(GetCommandText(entitySet), context, mergeOption) {
            this.metadata = entitySet;
        }

        /// <summary>
        /// Gets metadata for the EntitySet.
        /// </summary>
        public EntitySet Metadata {
            get { return this.metadata; }
        }

        /// <summary>
        /// Gets qualified entity set name. Used to associate entities with the set.
        /// </summary>
        private string QualifiedEntitySetName {
            get { return this.Metadata.EntityContainer.Name + "." + this.Metadata.Name; }
        }

        /// <summary>
        /// Tracks a new entity for insertion when ObjectContext.SaveChanges is called.
        /// </summary>
        /// <param name="entity">Entity to insert.</param>
        public void InsertOnSaveChanges(T entity) {
            Utility.CheckArgumentNotNull(((object)entity), "entity");

            this.Context.AddObject(this.QualifiedEntitySetName, entity);
        }

        /// <summary>
        /// Removes an entity from the EntitySet. The entity will be deleted
        /// when ObjectContext.SaveChanges is called.
        /// </summary>
        /// <param name="entity">Entity to delete.</param>
        public void DeleteOnSaveChanges(T entity) {
            Utility.CheckArgumentNotNull(((object)entity), "entity");

            // check that the entity actually exists first
            ObjectStateEntry stateEntry;

            if (!this.Context.ObjectStateManager.TryGetObjectStateEntry(entity, out stateEntry)) {
                throw new ArgumentException(Messages.UntrackedEntity, "entity");
            }

            // now check that the entity belongs to the current entity set
            if (this.metadata != stateEntry.EntitySet) {
                throw new ArgumentException(Messages.DeletingFromWrongSet, "entity");
            }

            this.Context.DeleteObject(entity);
        }

        /// <summary>
        /// Attaches an existing entity to the current entity set.
        /// </summary>
        /// <param name="entity">Entity to attach.</param>
        public void Attach(T entity) {
            Utility.CheckArgumentNotNull(((object)entity), "entity");

            this.Context.AttachTo(this.QualifiedEntitySetName, entity);
        }

        /// <summary>
        /// Attaches the given entity or returns existing entity with the same key.
        /// </summary>
        /// <typeparam name="TEntity">Entity type.</typeparam>
        /// <param name="entity">Entity to attach.</param>
        /// <returns>Input entity or existing entity with the same key.</returns>
        public TEntity FindOrAttach<TEntity>(TEntity entity)
            where TEntity : T {
            if (null == (object)entity) {
                return default(TEntity);
            }
            EntityKey entityKey = this.Context.CreateEntityKey(this.QualifiedEntitySetName, entity);
            ObjectStateEntry existingStateEntry;
            if (this.Context.ObjectStateManager.TryGetObjectStateEntry(entityKey, out existingStateEntry) &&
                null != existingStateEntry.Entity) // A proxy entry may exist for the entity instance
            {
                try {
                    return (TEntity)existingStateEntry.Entity;
                }
                catch (InvalidCastException) {
                    throw new InvalidOperationException(Messages.AttachedEntityHasWrongType);
                }
            }
            else {
                Attach(entity);
                return entity;
            }
        }

        /// <summary>
        /// Gets all members of the EntitySet that are currently in memory.
        /// </summary>
        /// <returns>All tracked members of the EntitySet</returns>
        public IEnumerable<T> GetTrackedEntities() {
            return GetTrackedEntities(~EntityState.Detached);
        }

        /// <summary>
        /// Gets all members of the EntitySet that are currently in memory
        /// with the given state(s).
        /// </summary>
        /// <param name="state">Entity state flags.</param>
        /// <returns>Tracked members of the EntitySet in the given state.</returns>
        public IEnumerable<T> GetTrackedEntities(EntityState state) {
            return this.Context.ObjectStateManager.GetObjectStateEntries(state)
                .Where(IsMemberOfEntitySet).Select(e => e.Entity).Cast<T>();
        }

        private bool IsMemberOfEntitySet(ObjectStateEntry entry) {
            return !entry.IsRelationship // must be an entity
                && null != entry.Entity // must not be a key entry
                && entry.EntitySet == this.metadata; // must belong to the current set
        }

        private static EntitySet GetEntitySet(ObjectContext context, string containerName, string entitySetName) {
            Utility.CheckArgumentNotNull(context, "context");

            // if no container is specified, use the default for the context
            containerName = string.IsNullOrEmpty(containerName) ? context.DefaultContainerName : containerName;
            Utility.CheckArgumentNotNullOrEmpty(containerName, "containerName");

            // ensure the entity container exists
            EntityContainer container;
            if (!context.MetadataWorkspace.TryGetEntityContainer(containerName,
                DataSpace.CSpace, out container)) {
                throw new ArgumentException(String.Format(Messages.Culture, Messages.UnknownEntityContainer, containerName), "containerName");
            }

            EntitySet entitySet;

            if (string.IsNullOrEmpty(entitySetName)) {
                // if no entity set is specified, try to find a single entity set taking this type
                entitySet = GetDefaultEntitySet(context, container);
            }
            else if (!container.TryGetEntitySetByName(entitySetName, false, out entitySet)) {
                // ensure the requested entity set exists
                throw new ArgumentException(String.Format(Messages.Culture, Messages.UnknownEntitySet, entitySetName), "entitySetName");
            }

            return entitySet;
        }

        private static EntitySet GetDefaultEntitySet(ObjectContext context, EntityContainer container) {
            EntitySet entitySet;

            // register the assembly
            context.MetadataWorkspace.LoadFromAssembly(typeof(T).Assembly);

            // try to find a single entity set accepting the given type
            StructuralType edmType = GetEdmType(context.MetadataWorkspace);
            var candidates = from candidate in container.BaseEntitySets.OfType<EntitySet>()
                             where IsSubtype(candidate.ElementType, edmType)
                             select candidate;
            using (var candidateEnumerator = candidates.GetEnumerator()) {
                if (candidateEnumerator.MoveNext()) {
                    entitySet = candidateEnumerator.Current;
                    if (candidateEnumerator.MoveNext()) {
                        // more than one match
                        throw new InvalidOperationException(String.Format(CultureInfo.CurrentCulture, Messages.AmbiguousEntitySet, typeof(T)));
                    }
                }
                else {
                    // no matches
                    throw new InvalidOperationException(String.Format(CultureInfo.CurrentCulture, Messages.NoEntitySet, typeof(T)));
                }
            }
            return entitySet;
        }

        private static bool IsSubtype(EdmType baseType, EdmType derivedType) {
            while (derivedType != null) {
                if (derivedType == baseType) {
                    return true;
                }
                derivedType = derivedType.BaseType;
            }
            return false;
        }

        private static StructuralType GetEdmType(MetadataWorkspace workspace) {
            StructuralType objectSpaceType;
            workspace.LoadFromAssembly(typeof(T).Assembly);
            if (!workspace.TryGetItem<StructuralType>(typeof(T).FullName, DataSpace.OSpace, out objectSpaceType)) {
                throw new InvalidOperationException(String.Format(CultureInfo.CurrentCulture, Messages.UnableToFindMetadataForType, typeof(T)));
            }
            StructuralType edmSpaceType = workspace.GetEdmSpaceType(objectSpaceType);
            return edmSpaceType;
        }

        private static string GetCommandText(EntitySet entitySet) {
            Utility.CheckArgumentNotNull(entitySet, "entitySet");

            // to query an entity set, simply name it
            string containerName = entitySet.EntityContainer.Name;
            string entitySetName = entitySet.Name;

            // quote the identifiers
            return QuoteIdentifier(containerName) + "." + QuoteIdentifier(entitySetName);
        }

        private static string QuoteIdentifier(string identifier) {
            Utility.CheckArgumentNotNullOrEmpty(identifier, "identifier");
            return "[" + identifier.Replace("]", "]]") + "]";
        }
    }
}
www.java2v.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.