* src/**/*: Flush; syncs to DbLinq r1053. Adds
authorJonathan Pryor <jpryor@novell.com>
Fri, 24 Apr 2009 23:47:48 +0000 (23:47 -0000)
committerJonathan Pryor <jpryor@novell.com>
Fri, 24 Apr 2009 23:47:48 +0000 (23:47 -0000)
  DataContext(string,MappingSource) support, the beginnings of object
  tracking, more tests...

svn path=/trunk/mcs/; revision=132640

17 files changed:
1  2 
mcs/class/System.Data.Linq/ChangeLog
mcs/class/System.Data.Linq/System.Data.Linq.dll.sources
mcs/class/System.Data.Linq/src/DbLinq/Data/Linq/DataContext.cs
mcs/class/System.Data.Linq/src/DbLinq/Data/Linq/EntityRef.cs
mcs/class/System.Data.Linq/src/DbLinq/Data/Linq/EntitySet.cs
mcs/class/System.Data.Linq/src/DbLinq/Data/Linq/Implementation/EntityTracker.cs
mcs/class/System.Data.Linq/src/DbLinq/Data/Linq/Mapping/XmlMappingSource.cs
mcs/class/System.Data.Linq/src/DbLinq/Data/Linq/Sugar/Implementation/DataMapper.cs
mcs/class/System.Data.Linq/src/DbLinq/Data/Linq/Sugar/Implementation/QueryRunner.cs
mcs/class/System.Data.Linq/src/DbLinq/DbLinq.csproj
mcs/class/System.Data.Linq/src/DbLinq/System.Data.Linq.csproj
mcs/class/System.Data.Linq/src/DbLinq/System.Data.Linq/System.Data.Linq.Mapping/XmlMappingSource.cs
mcs/class/System.Data.Linq/src/DbLinq/Test/DataContextTest.cs
mcs/class/System.Data.Linq/src/DbLinq/Test/Providers/Attach.cs
mcs/class/System.Data.Linq/src/DbLinq/Test/Providers/ReadTest.cs
mcs/class/System.Data.Linq/src/DbLinq/Test/Providers/ReadTests_EntitySet.cs
mcs/class/System.Data.Linq/src/DbLinq/Vendor/Implementation/Vendor.cs

index 6fe2ba9f418980714c46540e0ac23fb1e1e295c6,6fe2ba9f418980714c46540e0ac23fb1e1e295c6..fbcb2d4f076d47f7e5200ee69a91133c9412b603
@@@ -1,3 -1,3 +1,9 @@@
++2009-04-24  Jonathan Pryor  <jpryor@novell.com>
++
++      * src/**/*: Flush; syncs to DbLinq r1053.  Adds
++        DataContext(string,MappingSource) support, the beginnings of object
++        tracking, more tests...
++
  2009-04-08  Jonathan Pryor  <jpryor@novell.com>
  
        * **/* (svn:ignore): Ignore generated files and directories.
index 9c32d4c67c55bf0ba3f54fb6f9c53b347233f22a,9c32d4c67c55bf0ba3f54fb6f9c53b347233f22a..43767f4c5783e4d8a95c0c732acbf7865c7ca41a
@@@ -26,10 -26,10 +26,12 @@@ src/DbLinq/Data/Linq/Identity/Implement
  src/DbLinq/Data/Linq/IEntityMap.cs
  src/DbLinq/Data/Linq/IExecuteResult.cs
  src/DbLinq/Data/Linq/IMemberModificationHandler.cs
++src/DbLinq/Data/Linq/Implementation/DisabledEntityTracker.cs
  src/DbLinq/Data/Linq/Implementation/EntityMap.cs
  src/DbLinq/Data/Linq/Implementation/EntityState.cs
  src/DbLinq/Data/Linq/Implementation/EntityTrack.cs
  src/DbLinq/Data/Linq/Implementation/EntityTracker.cs
++src/DbLinq/Data/Linq/Implementation/IEntityTracker.cs
  src/DbLinq/Data/Linq/Implementation/MemberModificationHandler.cs
  src/DbLinq/Data/Linq/Implementation/QueryProvider.cs
  src/DbLinq/Data/Linq/Implementation/VendorProvider.cs
@@@ -45,6 -45,6 +47,7 @@@ src/DbLinq/Data/Linq/Mapping/Attributed
  src/DbLinq/Data/Linq/Mapping/AttributedMetaType.cs
  src/DbLinq/Data/Linq/Mapping/AttributeMappingSource.cs
  src/DbLinq/Data/Linq/Mapping/MappingContext.cs
++src/DbLinq/Data/Linq/Mapping/XmlMappingSource.cs
  src/DbLinq/Data/Linq/RefreshMode.cs
  src/DbLinq/Data/Linq/SqlClient/FirebirdProvider.cs
  src/DbLinq/Data/Linq/SqlClient/IngresProvider.cs
@@@ -266,7 -266,7 +269,6 @@@ src/DbLinq/System.Data.Linq/System.Data
  src/DbLinq/System.Data.Linq/System.Data.Linq.Mapping/ResultTypeAttribute.cs
  src/DbLinq/System.Data.Linq/System.Data.Linq.Mapping/TableAttribute.cs
  src/DbLinq/System.Data.Linq/System.Data.Linq.Mapping/UpdateCheck.cs
--src/DbLinq/System.Data.Linq/System.Data.Linq.Mapping/XmlMappingSource.cs
  src/DbLinq/System.Data.Linq/System.Data.Linq.SqlClient.Implementation/ObjectMaterializer.cs
  src/DbLinq/System.Data.Linq/System.Data.Linq.SqlClient/SqlHelpers.cs
  src/DbLinq/System.Data.Linq/System.Data.Linq.SqlClient/SqlMethods.cs
index 2eaa680c1633f5ef70fc7d1495da4c2abeaec0ce,2eaa680c1633f5ef70fc7d1495da4c2abeaec0ce..d00cbd7466b0b271bf4761662b5e0c7064509bf3
@@@ -83,7 -83,7 +83,26 @@@ namespace DbLinq.Data.Lin
          internal IDatabaseContext DatabaseContext { get; private set; }\r
          // /all properties...\r
  \r
--        private readonly EntityTracker entityTracker = new EntityTracker();\r
++        private bool objectTrackingEnabled = true;\r
++        private bool deferredLoadingEnabled = true;\r
++\r
++        private IEntityTracker entityTracker;\r
++        private IEntityTracker EntityTracker\r
++        {\r
++            get\r
++            {\r
++                if (this.entityTracker == null)\r
++                {\r
++                    if (this.ObjectTrackingEnabled)\r
++                        this.entityTracker = new EntityTracker();\r
++                    else\r
++                        this.entityTracker = new DisabledEntityTracker();\r
++                }\r
++                return this.entityTracker;\r
++            }\r
++        }\r
++\r
++\r
  \r
          private IIdentityReaderFactory identityReaderFactory;\r
          private readonly IDictionary<Type, IIdentityReader> identityReaders = new Dictionary<Type, IIdentityReader>();\r
          [DbLinqToDo]\r
          public DataContext(string fileOrServerOrConnection, MappingSource mapping)\r
          {\r
--            throw new NotImplementedException();\r
++            if (fileOrServerOrConnection == null)\r
++                throw new ArgumentNullException("fileOrServerOrConnection");\r
++            if (mapping == null)\r
++                throw new ArgumentNullException("mapping");\r
++\r
++            if (File.Exists(fileOrServerOrConnection))\r
++                throw new NotImplementedException("File names not supported.");\r
++\r
++            // Is this a decent server name check?\r
++            // It assumes that the connection string will have at least 2\r
++            // parameters (separated by ';')\r
++            if (!fileOrServerOrConnection.Contains(";"))\r
++                throw new NotImplementedException("Server name not supported.");\r
++\r
++            // Assume it's a connection string...\r
++            IVendor ivendor = GetVendor(fileOrServerOrConnection);\r
++\r
++            IDbConnection dbConnection = ivendor.CreateDbConnection(fileOrServerOrConnection);\r
++            Init(new DatabaseContext(dbConnection), mapping, ivendor);\r
          }\r
  \r
          /// <summary>\r
          /// <param name="failureMode"></param>\r
          public virtual void SubmitChanges(ConflictMode failureMode)\r
          {\r
++            if (this.objectTrackingEnabled == false)\r
++                throw new InvalidOperationException("Object tracking is not enabled for the current data context instance.");\r
              using (DatabaseContext.OpenConnection()) //ConnMgr will close connection for us\r
              using (IDatabaseTransaction transaction = DatabaseContext.Transaction())\r
              {\r
                  var queryContext = new QueryContext(this);\r
--                var entityTracks = entityTracker.EnumerateAll().ToList();\r
++                var entityTracks = EntityTracker.EnumerateAll().ToList();\r
                  foreach (var entityTrack in entityTracks)\r
                  {\r
                      switch (entityTrack.EntityState)\r
              if (identityKey == null) // if we don't have an entitykey here, it means that the entity has no PK\r
                  return entity;\r
              // even \r
--            var registeredEntityTrack = entityTracker.FindByIdentity(identityKey);\r
++            var registeredEntityTrack = EntityTracker.FindByIdentity(identityKey);\r
              if (registeredEntityTrack != null)\r
                  return registeredEntityTrack.Entity;\r
              return null;\r
                  return entity;\r
  \r
              // try to find an already registered entity and return it\r
--            var registeredEntityTrack = entityTracker.FindByIdentity(identityKey);\r
++            var registeredEntityTrack = EntityTracker.FindByIdentity(identityKey);\r
              if (registeredEntityTrack != null)\r
                  return registeredEntityTrack.Entity;\r
  \r
              // otherwise, register and return\r
--            entityTracker.RegisterToWatch(entity, identityKey);\r
++            EntityTracker.RegisterToWatch(entity, identityKey);\r
              return entity;\r
          }\r
  \r
          readonly IDataMapper DataMapper = ObjectFactory.Get<IDataMapper>();\r
          private void SetEntityRefQueries(object entity)\r
          {\r
++            if (!this.deferredLoadingEnabled)\r
++                return;\r
++\r
++            // BUG: This is ignoring External Mappings from XmlMappingSource.\r
++\r
              Type thisType = entity.GetType();\r
              IList<MemberInfo> properties = DataMapper.GetEntityRefAssociations(thisType);\r
  \r
          /// <param name="entity"></param>\r
          private void SetEntitySetsQueries(object entity)\r
          {\r
++            if (!this.deferredLoadingEnabled)\r
++                return;\r
++\r
++            // BUG: This is ignoring External Mappings from XmlMappingSource.\r
++\r
              IList<MemberInfo> properties = DataMapper.GetEntitySetAssociations(entity.GetType());\r
              \r
              if (properties.Any()) {\r
          /// <param name="entity"></param>\r
          internal void RegisterInsert(object entity)\r
          {\r
--            entityTracker.RegisterToInsert(entity);\r
++            EntityTracker.RegisterToInsert(entity);\r
          }\r
  \r
          /// <summary>\r
              if (entity == null)\r
                  throw new ArgumentNullException("entity");\r
  \r
++            if (!this.objectTrackingEnabled)\r
++                return;\r
++\r
              var identityReader = _GetIdentityReader(entity.GetType());\r
              var identityKey = identityReader.GetIdentityKey(entity);\r
--            Console.WriteLine("# identityKey={0}", identityKey == null ? "<null>" : identityKey.ToString());\r
              // if we have no key, we can not watch\r
              if (identityKey == null)\r
                  return;\r
              // register entity\r
--            entityTracker.RegisterToWatch(entity, identityKey);\r
++            EntityTracker.RegisterToWatch(entity, identityKey);\r
          }\r
  \r
          /// <summary>\r
          /// <returns></returns>\r
          internal object Register(object entity)\r
          {\r
++            if (! this.objectTrackingEnabled)\r
++                return entity;\r
              var registeredEntity = _GetOrRegisterEntity(entity);\r
              // the fact of registering again clears the modified state, so we're... clear with that\r
              MemberModificationHandler.Register(registeredEntity, Mapping);\r
          /// <param name="entityOriginalState"></param>\r
          internal void RegisterUpdate(object entity, object entityOriginalState)\r
          {\r
++            if (!this.objectTrackingEnabled)\r
++                return;\r
              RegisterUpdate(entity);\r
              MemberModificationHandler.Register(entity, entityOriginalState, Mapping);\r
          }\r
          /// <param name="entity"></param>\r
          internal void RegisterUpdateAgain(object entity)\r
          {\r
++            if (!this.objectTrackingEnabled)\r
++                return;\r
              MemberModificationHandler.ClearModified(entity, Mapping);\r
          }\r
  \r
          /// <param name="entity"></param>\r
          internal void RegisterDelete(object entity)\r
          {\r
--            entityTracker.RegisterToDelete(entity);\r
++            if (!this.objectTrackingEnabled)\r
++                return;\r
++            EntityTracker.RegisterToDelete(entity);\r
          }\r
  \r
          /// <summary>\r
          /// <param name="entity"></param>\r
          internal void UnregisterDelete(object entity)\r
          {\r
--            entityTracker.RegisterDeleted(entity);\r
++            if (!this.objectTrackingEnabled)\r
++                return;\r
++            EntityTracker.RegisterDeleted(entity);\r
          }\r
  \r
          #endregion\r
              var inserts = new List<object>();\r
              var updates = new List<object>();\r
              var deletes = new List<object>();\r
--            foreach (var entityTrack in entityTracker.EnumerateAll())\r
++            foreach (var entityTrack in EntityTracker.EnumerateAll())\r
              {\r
                  switch (entityTrack.EntityState)\r
                  {\r
          /// Gets or sets the load options\r
          /// </summary>\r
          [DbLinqToDo]\r
--        public DataLoadOptions LoadOptions { get; set; }\r
++        public DataLoadOptions LoadOptions \r
++        {\r
++            get { throw new NotImplementedException(); }\r
++            set { throw new NotImplementedException(); }\r
++        }\r
  \r
          public DbTransaction Transaction { get; set; }\r
  \r
              }\r
          }\r
  \r
--\r
--        [DbLinqToDo]\r
          public bool ObjectTrackingEnabled\r
          {\r
--            get { throw new NotImplementedException(); }\r
--            set { throw new NotImplementedException(); }\r
++            get { return this.objectTrackingEnabled; }\r
++            set \r
++            {\r
++                if (this.entityTracker != null && value != this.objectTrackingEnabled)\r
++                    throw new InvalidOperationException("Data context options cannot be modified after results have been returned from a query.");\r
++                this.objectTrackingEnabled = value;\r
++            }\r
          }\r
  \r
          [DbLinqToDo]\r
              set { throw new NotImplementedException(); }\r
          }\r
  \r
--        [DbLinqToDo]\r
          public bool DeferredLoadingEnabled\r
          {\r
--            get { throw new NotImplementedException(); }\r
--            set { throw new NotImplementedException(); }\r
++            get { return this.deferredLoadingEnabled; }\r
++            set\r
++            {\r
++                if (this.entityTracker != null && value != this.deferredLoadingEnabled)\r
++                    throw new InvalidOperationException("Data context options cannot be modified after results have been returned from a query.");\r
++                this.deferredLoadingEnabled = value;\r
++            }\r
          }\r
  \r
          [DbLinqToDo]\r
index a380e60f3c223affbb6bb2cc916e8d74ea2e13e7,a380e60f3c223affbb6bb2cc916e8d74ea2e13e7..916fcb0a8de7ec448dfb902399c5d31e9cc4646d
@@@ -82,6 -82,6 +82,7 @@@ namespace DbLinq.Data.Lin
                          if (entity != null)\r
                              throw new InvalidOperationException ("Sequence contains more than one element");\r
                          entity = s;\r
++                        hasLoadedOrAssignedValue = true;\r
                      }\r
                      source = null;\r
                  }\r
index 18d36d3e8f7c898fe97d2743e6cdae5ebda25c42,18d36d3e8f7c898fe97d2743e6cdae5ebda25c42..45a2ffa6f092cd996dd7557d67a868aa6f982ae3
@@@ -125,6 -125,6 +125,9 @@@ namespace DbLinq.Data.Lin
                  return;\r
              sourceAsList.Add(entity);\r
              OnAdd(entity);\r
++            ListChangedEventHandler handler = ListChanged;\r
++            if (handler != null)\r
++                handler(this, new ListChangedEventArgs(ListChangedType.ItemAdded, sourceAsList.Count - 1));\r
          }\r
  \r
          [DbLinqToDo]\r
                  throw new ArgumentOutOfRangeException();\r
              OnAdd(entity);\r
              sourceAsList.Insert(index, entity);\r
++            ListChangedEventHandler handler = ListChanged;\r
++            if (handler != null)\r
++                handler(this, new ListChangedEventArgs(ListChangedType.ItemAdded, index));\r
          }\r
  \r
          /// <summary>\r
          {\r
              OnRemove(sourceAsList[index]);\r
              sourceAsList.RemoveAt(index);\r
++            ListChangedEventHandler handler = ListChanged;\r
++            if (handler != null)\r
++                handler(this, new ListChangedEventArgs(ListChangedType.ItemDeleted, index));\r
          }\r
  \r
          /// <summary>\r
          {\r
              get\r
              {\r
--                return Source.ElementAt(index);\r
++                if(! this.HasLoadedOrAssignedValues)\r
++                    return Source.ElementAt(index);\r
++                return sourceAsList[index];\r
              }\r
              set\r
              {\r
  \r
          #region ICollection<TEntity> Members\r
  \r
++        private void clear()\r
++        {\r
++            sourceAsList.Clear();\r
++            Source = Enumerable.Empty<TEntity>();\r
++        }\r
++\r
          /// <summary>\r
          /// Removes all items in collection\r
          /// </summary>\r
          public void Clear()\r
          {\r
--            while (sourceAsList.Count > 0)\r
--                Remove(sourceAsList [0]);\r
--            Source = Enumerable.Empty<TEntity>();\r
++            clear();\r
++            ListChangedEventHandler handler = ListChanged;\r
++            if (handler != null)\r
++                handler(this, new ListChangedEventArgs(ListChangedType.Reset, -1));\r
          }\r
  \r
          /// <summary>\r
          /// <returns>\r
          ///   <c>true</c> if [contains] [the specified entity]; otherwise, <c>false</c>.\r
          /// </returns>\r
++        [DbLinqToDo]\r
          public bool Contains(TEntity entity)\r
          {\r
--            return Source.Contains(entity);\r
++            return sourceAsList.Contains(entity);\r
          }\r
  \r
          /// <summary>\r
          {\r
              get\r
              {\r
++                if (!this.HasLoadedOrAssignedValues)\r
++                    return Source.Count();\r
                  return sourceAsList.Count;\r
              }\r
          }\r
          public bool Remove(TEntity entity)\r
          {\r
              OnRemove(entity);\r
++            ListChangedEventHandler handler = ListChanged;\r
++            int i = sourceAsList.IndexOf(entity);\r
++            if (handler != null)\r
++                handler(this, new ListChangedEventArgs(ListChangedType.ItemDeleted, i));\r
              return sourceAsList.Remove(entity);\r
          }\r
  \r
          /// </value>\r
          public bool IsDeferred\r
          {\r
--            get { return Source is IQueryable; }\r
++            get { return SourceInUse == null && Source is IQueryable; }\r
          }\r
  \r
          /// <summary>\r
          public void Assign(IEnumerable<TEntity> entitySource)\r
          {\r
              // notifies removals and adds\r
--            Clear();\r
++            clear();\r
              foreach (var entity in entitySource)\r
++            {\r
                  OnAdd(entity);\r
++            }\r
              this.Source = entitySource;\r
              this.SourceInUse = sourceAsList;\r
++            ListChangedEventHandler handler = ListChanged;\r
++            if (handler != null)\r
++                handler(this, new ListChangedEventArgs(ListChangedType.Reset,-1));\r
          }\r
  \r
          /// <summary>\r
          /// </summary>\r
          public void Load()\r
          {\r
--            this.sourceAsList.Count();\r
++            IList<TEntity> list = this.sourceAsList;\r
          }\r
  \r
          /// <summary>\r
index fc0b0299aac3e0ce98709172f6425715386c0361,fc0b0299aac3e0ce98709172f6425715386c0361..b722502d67684d7dde90bdf34696a368a05ca872
@@@ -43,7 -43,7 +43,7 @@@ namespace DbLinq.Data.Linq.Implementati
      /// <summary>\r
      /// List of entities, with their corresponding state (to insert, to watch, to delete)\r
      /// </summary>\r
--    internal class EntityTracker\r
++    internal class EntityTracker : IEntityTracker\r
      {\r
          /// <summary>\r
          /// Entities being watched\r
@@@ -63,7 -63,7 +63,7 @@@
          /// </summary>\r
          /// <param name="entity"></param>\r
          /// <returns></returns>\r
--        public EntityTrack FindByReference(object entity)\r
++        private EntityTrack FindByReference(object entity)\r
          {\r
              lock (lockObject)\r
                  return (from e in entities where e.Entity == entity select e).FirstOrDefault();\r
              lock (lockObject)\r
              {\r
                  var entityTrack = FindByReference(entity);\r
--                Console.WriteLine("# RegisterToWatch({0}, {1})", entity, identityKey);\r
--                Console.WriteLine("# entityTrack={0}", entityTrack);\r
                  if (entityTrack == null)\r
                  {\r
                      entityTrack = new EntityTrack(entity, EntityState.ToWatch) { IdentityKey = identityKey };\r
                  }\r
                  else\r
                  {\r
--                    Console.WriteLine("# have entityTrack; entityState={0}", entityTrack.EntityState);\r
                      // changes the state of the current entity\r
                      switch (entityTrack.EntityState)\r
                      {\r
index 0000000000000000000000000000000000000000,0000000000000000000000000000000000000000..4d52557e075b57551c84a2ed158ef55e10456a19
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,1180 @@@
++#region MIT license\r
++// \r
++// MIT license\r
++//\r
++// Copyright (c) 2007-2008 Jiri Moudry, Stefan Klinger\r
++// \r
++// Permission is hereby granted, free of charge, to any person obtaining a copy\r
++// of this software and associated documentation files (the "Software"), to deal\r
++// in the Software without restriction, including without limitation the rights\r
++// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r
++// copies of the Software, and to permit persons to whom the Software is\r
++// furnished to do so, subject to the following conditions:\r
++// \r
++// The above copyright notice and this permission notice shall be included in\r
++// all copies or substantial portions of the Software.\r
++// \r
++// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
++// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
++// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r
++// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r
++// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r
++// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\r
++// THE SOFTWARE.\r
++// \r
++#endregion\r
++\r
++#region grammar\r
++/* ----------------\r
++default namespace = "http://schemas.microsoft.com/linqtosql/mapping/2007"\r
++grammar {\r
++\r
++start = element Database { Database }\r
++\r
++Database = {\r
++  element Table { Table }*,\r
++  element Function { Function }*,\r
++  attribute Name { text }?,\r
++  attribute Provider { text }?\r
++}\r
++\r
++Table = {\r
++  element Type { Type },\r
++  attribute Name { text }?,\r
++  attribute Member { text }?\r
++}\r
++\r
++Type = {\r
++  {\r
++    element Column { Column }* |\r
++    element Association { Association }*\r
++  }*,\r
++  element Type { Type }*,\r
++  attribute Name { text },\r
++  attribute InheritanceCode { text }?,\r
++  attribute IsInheritanceDefault { boolean }?\r
++}\r
++\r
++Column = {\r
++  attribute Name { text }?,\r
++  attribute Member { text },\r
++  attribute Storage { text }?,\r
++  attribute DbType { text }?,\r
++  attribute IsPrimaryKey { boolean }?,\r
++  attribute IsDbGenerated { boolean }?,\r
++  attribute CanBeNull { boolean }?,\r
++  attribute UpdateCheck { UpdateCheck }?,\r
++  attribute IsDiscriminator { boolean }?,\r
++  attribute Expression { text }?,\r
++  attribute IsVersion { boolean }?,\r
++  attribute AutoSync { AutoSync}?\r
++}\r
++\r
++Association = {\r
++  attribute Name { text }?,\r
++  attribute Member { text },\r
++  attribute Storage { text }?,\r
++  attribute ThisKey { text }?,\r
++  attribute OtherKey { text }?,\r
++  attribute IsForeignKey { boolean }?,\r
++  attribute IsUnique { boolean }?,\r
++  attribute DeleteRule { text }?,\r
++  attribute DeleteOnNull { boolean }?\r
++}\r
++\r
++Function = {\r
++  element Parameter { Parameter }*,\r
++  {\r
++    element ElementType { Type }* |\r
++    element Return { Return }\r
++  },\r
++  attribute Name { text }?,\r
++  attribute Method { text },\r
++  attribute IsComposable { boolean }?\r
++}\r
++\r
++Parameter = {\r
++  attribute Name { text }?,\r
++  attribute Parameter { text },\r
++  attribute DbType { text }?,\r
++  attribute Direction { ParameterDirection }?\r
++}\r
++\r
++Return = attribute DbType { text}?\r
++\r
++UpdateCheck = "Always" | "Never" | "WhenChanged"\r
++ParameterDirection = "In" | "Out" | "InOut"\r
++AutoSync = "Never" | "OnInsert" | "OnUpdate" | "Always" | "Default"\r
++\r
++}\r
++---------------- */\r
++#endregion\r
++\r
++using System;\r
++using System.Collections.Generic;\r
++using System.Collections.ObjectModel;\r
++using System.IO;\r
++using System.Linq;\r
++using System.Reflection;\r
++using System.Xml;\r
++using DbLinq;\r
++using DbLinq.Schema.Dbml;\r
++using DbLinq.Util;\r
++\r
++#if MONO_STRICT\r
++namespace System.Data.Linq.Mapping\r
++#else\r
++namespace DbLinq.Data.Linq.Mapping\r
++#endif\r
++{\r
++    public sealed class XmlMappingSource : System.Data.Linq.Mapping.MappingSource\r
++    {\r
++        DbmlDatabase db;\r
++\r
++        XmlMappingSource(XmlReader reader)\r
++        {\r
++            db = new DbmlDatabase(reader);\r
++        }\r
++\r
++        public static XmlMappingSource FromReader(XmlReader reader)\r
++        {\r
++            return new XmlMappingSource(reader);\r
++        }\r
++\r
++        public static XmlMappingSource FromStream(Stream stream)\r
++        {\r
++            return FromReader(XmlReader.Create(stream));\r
++        }\r
++\r
++        public static XmlMappingSource FromUrl(string url)\r
++        {\r
++            return FromReader(XmlReader.Create(url));\r
++        }\r
++\r
++        public static XmlMappingSource FromXml(string xml)\r
++        {\r
++            return FromReader(XmlReader.Create(new StringReader(xml)));\r
++        }\r
++\r
++        protected override System.Data.Linq.Mapping.MetaModel CreateModel(System.Type dataContextType)\r
++        {\r
++            return new XmlMetaModel(this, db, dataContextType);\r
++        }\r
++\r
++\r
++        abstract class DbmlItem\r
++        {\r
++            public const string DbmlNamespace = "http://schemas.microsoft.com/linqtosql/mapping/2007";\r
++\r
++            public void ReadEmptyContent(XmlReader r, string name)\r
++            {\r
++                if (r.IsEmptyElement)\r
++                    r.ReadStartElement(name, DbmlNamespace);\r
++                else\r
++                {\r
++                    r.ReadStartElement(name, DbmlNamespace);\r
++                    for (r.MoveToContent(); r.NodeType != XmlNodeType.EndElement; r.MoveToContent())\r
++                    {\r
++                        if (r.NamespaceURI != DbmlNamespace)\r
++                            r.Skip();\r
++                        throw UnexpectedItemError(r);\r
++                    }\r
++                    r.ReadEndElement();\r
++                }\r
++            }\r
++            public bool GetBooleanAttribute(XmlReader r, string attributeName)\r
++            {\r
++                return r.GetAttribute(attributeName) == "true";\r
++            }\r
++            public UpdateCheck GetUpdateCheckAttribute(XmlReader r, string attributeName)\r
++            {\r
++                var s = r.GetAttribute(attributeName);\r
++                return s != null ? (UpdateCheck)Enum.Parse(typeof(UpdateCheck), s) : default(UpdateCheck);\r
++            }\r
++            public AutoSync GetAutoSyncAttribute(XmlReader r, string attributeName)\r
++            {\r
++                var s = r.GetAttribute(attributeName);\r
++                return s != null ? (AutoSync)Enum.Parse(typeof(AutoSync), s) : default(AutoSync);\r
++            }\r
++            public T GetEnumAttribute<T>(XmlReader r, string attributeName)\r
++            {\r
++                var s = r.GetAttribute(attributeName);\r
++                return s != null ? (T)Enum.Parse(typeof(T), s) : default(T);\r
++            }\r
++            public XmlException UnexpectedItemError(XmlReader r)\r
++            {\r
++                return new XmlException(String.Format("Unexpected dbml element '{0}'", r.LocalName));\r
++            }\r
++        }\r
++        class DbmlDatabase : DbmlItem\r
++        {\r
++            public string Name;\r
++            public string Provider;\r
++            public List<DbmlTable> Tables = new List<DbmlTable>();\r
++            public List<DbmlFunction> Functions = new List<DbmlFunction>();\r
++\r
++            public DbmlDatabase(XmlReader r)\r
++            {\r
++                r.MoveToContent();\r
++                Name = r.GetAttribute("Name");\r
++                Provider = r.GetAttribute("Provider");\r
++                if (r.IsEmptyElement)\r
++                    r.ReadStartElement("Database", DbmlNamespace);\r
++                else\r
++                {\r
++                    r.ReadStartElement("Database", DbmlNamespace);\r
++                    for (r.MoveToContent(); r.NodeType != XmlNodeType.EndElement; r.MoveToContent())\r
++                    {\r
++                        if (r.NamespaceURI != DbmlNamespace)\r
++                            r.Skip();\r
++                        else\r
++                        {\r
++                            switch (r.LocalName)\r
++                            {\r
++                                case "Table":\r
++                                    Tables.Add(new DbmlTable(r));\r
++                                    break;\r
++                                case "Function":\r
++                                    Functions.Add(new DbmlFunction(r));\r
++                                    break;\r
++                                default:\r
++                                    throw UnexpectedItemError(r);\r
++                            }\r
++                        }\r
++                    }\r
++                    r.ReadEndElement();\r
++                }\r
++            }\r
++        }\r
++        class DbmlTable : DbmlItem\r
++        {\r
++            public DbmlType Type;\r
++            public string Name;\r
++            public string Member;\r
++\r
++            public DbmlTable(XmlReader r)\r
++            {\r
++                Name = r.GetAttribute("Name");\r
++                Member = r.GetAttribute("Member");\r
++                if (r.IsEmptyElement)\r
++                    r.ReadStartElement("Table", DbmlNamespace);\r
++                else\r
++                {\r
++                    r.ReadStartElement("Table", DbmlNamespace);\r
++                    for (r.MoveToContent(); r.NodeType != XmlNodeType.EndElement; r.MoveToContent())\r
++                    {\r
++                        if (r.NamespaceURI != DbmlNamespace)\r
++                            r.Skip();\r
++                        else\r
++                        {\r
++                            switch (r.LocalName)\r
++                            {\r
++                                case "Type":\r
++                                    Type = new DbmlType(r);\r
++                                    break;\r
++                                default:\r
++                                    throw UnexpectedItemError(r);\r
++                            }\r
++                        }\r
++                    }\r
++                    r.ReadEndElement();\r
++                }\r
++            }\r
++        }\r
++        class DbmlType : DbmlItem\r
++        {\r
++            public List<DbmlColumn> Columns = new List<DbmlColumn>();\r
++            public List<DbmlAssociation> Associations = new List<DbmlAssociation>();\r
++            public List<DbmlType> Types = new List<DbmlType>();\r
++            public string Name;\r
++            public string InheritanceCode;\r
++            public bool IsInheritanceDefault;\r
++\r
++            public DbmlType(XmlReader r)\r
++            {\r
++                Name = r.GetAttribute("Name");\r
++                InheritanceCode = r.GetAttribute("InheritanceCode");\r
++                IsInheritanceDefault = GetBooleanAttribute(r, "IsInheritanceDefault");\r
++                if (r.IsEmptyElement)\r
++                    r.ReadStartElement("Type", DbmlNamespace);\r
++                else\r
++                {\r
++                    r.ReadStartElement("Type", DbmlNamespace);\r
++                    for (r.MoveToContent(); r.NodeType != XmlNodeType.EndElement; r.MoveToContent())\r
++                    {\r
++                        if (r.NamespaceURI != DbmlNamespace)\r
++                            r.Skip();\r
++                        else\r
++                        {\r
++                            switch (r.LocalName)\r
++                            {\r
++                                case "Column":\r
++                                    Columns.Add(new DbmlColumn(r));\r
++                                    break;\r
++                                case "Association":\r
++                                    Associations.Add(new DbmlAssociation(r));\r
++                                    break;\r
++                                case "Type":\r
++                                    Types.Add(new DbmlType(r));\r
++                                    break;\r
++                                default:\r
++                                    throw UnexpectedItemError(r);\r
++                            }\r
++                        }\r
++                    }\r
++                    r.ReadEndElement();\r
++                }\r
++            }\r
++        }\r
++\r
++        class DbmlMemberBase : DbmlItem\r
++        {\r
++            public string Name;\r
++            public string Member;\r
++            public string Storage;\r
++        }\r
++\r
++        class DbmlColumn : DbmlMemberBase\r
++        {\r
++            public string DbType;\r
++            public bool IsPrimaryKey;\r
++            public bool IsDbGenerated;\r
++            public bool CanBeNull;\r
++            public System.Data.Linq.Mapping.UpdateCheck UpdateCheck;\r
++            public bool IsDiscriminator;\r
++            public string Expression;\r
++            public bool IsVersion;\r
++            public System.Data.Linq.Mapping.AutoSync AutoSync;\r
++\r
++            public DbmlColumn(XmlReader r)\r
++            {\r
++                Member = r.GetAttribute("Member");\r
++                Name = r.GetAttribute("Name") ?? Member;\r
++                Storage = r.GetAttribute("Storage");\r
++                DbType = r.GetAttribute("DbType");\r
++                IsPrimaryKey = GetBooleanAttribute(r, "IsPrimaryKey");\r
++                IsDbGenerated = GetBooleanAttribute(r, "IsDbGenerated");\r
++                CanBeNull = GetBooleanAttribute(r, "CanBeNull");\r
++                UpdateCheck = GetEnumAttribute<System.Data.Linq.Mapping.UpdateCheck>(r, "UpdateCheck");\r
++                IsDiscriminator = GetBooleanAttribute(r, "IsDiscriminator");\r
++                Expression = r.GetAttribute("Expression");\r
++                IsVersion = GetBooleanAttribute(r, "IsVersion");\r
++                AutoSync = GetEnumAttribute<System.Data.Linq.Mapping.AutoSync>(r, "AutoSync");\r
++                ReadEmptyContent(r, "Column");\r
++            }\r
++        }\r
++        class DbmlAssociation : DbmlMemberBase\r
++        {\r
++            public string ThisKey;\r
++            public string OtherKey;\r
++            public bool IsForeignKey;\r
++            public bool IsUnique;\r
++            public string DeleteRule;\r
++            public bool DeleteOnNull;\r
++\r
++            public DbmlAssociation(XmlReader r)\r
++            {\r
++                Name = r.GetAttribute("Name");\r
++                Member = r.GetAttribute("Member");\r
++                Storage = r.GetAttribute("Storage");\r
++                ThisKey = r.GetAttribute("ThisKey");\r
++                OtherKey = r.GetAttribute("OtherKey");\r
++                IsForeignKey = GetBooleanAttribute(r, "IsForeignKey");\r
++                IsUnique = GetBooleanAttribute(r, "IsUnique");\r
++                DeleteRule = r.GetAttribute("DeleteRule");\r
++                DeleteOnNull = GetBooleanAttribute(r, "DeleteOnNull");\r
++                ReadEmptyContent(r, "Association");\r
++            }\r
++        }\r
++        class DbmlFunction : DbmlItem\r
++        {\r
++            public string Name;\r
++            public string Method;\r
++            public bool IsComposable;\r
++            public List<DbmlParameter> Parameters = new List<DbmlParameter>();\r
++            public List<DbmlType> ElementTypes = new List<DbmlType>();\r
++            public DbmlReturn Return;\r
++\r
++            public DbmlFunction(XmlReader r)\r
++            {\r
++                Name = r.GetAttribute("Name");\r
++                Method = r.GetAttribute("Method");\r
++                IsComposable = GetBooleanAttribute(r, "IsComposable");\r
++                if (r.IsEmptyElement)\r
++                    r.ReadStartElement("Function", DbmlNamespace);\r
++                else\r
++                {\r
++                    r.ReadStartElement("Function", DbmlNamespace);\r
++                    for (r.MoveToContent(); r.NodeType != XmlNodeType.EndElement; r.MoveToContent())\r
++                    {\r
++                        if (r.NamespaceURI != DbmlNamespace)\r
++                            r.Skip();\r
++                        else\r
++                        {\r
++                            switch (r.LocalName)\r
++                            {\r
++                                case "Parameter":\r
++                                    Parameters.Add(new DbmlParameter(r));\r
++                                    break;\r
++                                case "ElementType":\r
++                                    ElementTypes.Add(new DbmlType(r));\r
++                                    break;\r
++                                case "Return":\r
++                                    Return = new DbmlReturn(r);\r
++                                    break;\r
++                                default:\r
++                                    throw UnexpectedItemError(r);\r
++                            }\r
++                        }\r
++                    }\r
++                    r.ReadEndElement();\r
++                }\r
++            }\r
++        }\r
++        class DbmlParameter : DbmlItem\r
++        {\r
++            public string Name;\r
++            public string Parameter;\r
++            public string DbType;\r
++            public ParameterDirection Direction;\r
++\r
++            public DbmlParameter(XmlReader r)\r
++            {\r
++                Name = r.GetAttribute("Name");\r
++                Parameter = r.GetAttribute("Parameter");\r
++                DbType = r.GetAttribute("DbType");\r
++                Direction = GetEnumAttribute<ParameterDirection>(r, "Direction");\r
++                ReadEmptyContent(r, "Parameter");\r
++            }\r
++        }\r
++        class DbmlReturn : DbmlItem\r
++        {\r
++            public string DbType;\r
++\r
++            public DbmlReturn(XmlReader r)\r
++            {\r
++                DbType = r.GetAttribute("DbType");\r
++                ReadEmptyContent(r, "Return");\r
++            }\r
++        }\r
++\r
++        class XmlMetaModel : System.Data.Linq.Mapping.MetaModel\r
++        {\r
++            System.Data.Linq.Mapping.MappingSource source;\r
++            DbmlDatabase d;\r
++            System.Type context_type;\r
++            System.Data.Linq.Mapping.MetaFunction[] functions;\r
++            System.Data.Linq.Mapping.MetaTable[] tables;\r
++            Dictionary<System.Type, XmlMetaType> types;\r
++\r
++            public XmlMetaModel(System.Data.Linq.Mapping.MappingSource source, DbmlDatabase database, System.Type contextType)\r
++            {\r
++                this.source = source;\r
++                this.d = database;\r
++                this.context_type = contextType;\r
++                RegisterTypes();\r
++            }\r
++\r
++            void RegisterTypes()\r
++            {\r
++                types = new Dictionary<System.Type, XmlMetaType>();\r
++                foreach (var t in d.Tables)\r
++                    RegisterTypeAndDescendants(t.Type);\r
++            }\r
++\r
++            void RegisterTypeAndDescendants(DbmlType dt)\r
++            {\r
++\r
++                System.Type t = GetTypeFromName(dt.Name);\r
++                if (t == null)\r
++                    throw new ArgumentException(String.Format("type '{0}' not found", dt.Name));\r
++                if (types.ContainsKey(t))\r
++                    return;\r
++                types.Add(t, new XmlMetaType(this, dt));\r
++                foreach (var cdt in dt.Types)\r
++                    RegisterTypeAndDescendants(cdt);\r
++            }\r
++\r
++            public override System.Type ContextType\r
++            {\r
++                get { return context_type; }\r
++            }\r
++\r
++            public override string DatabaseName\r
++            {\r
++                get { return d.Name; }\r
++            }\r
++\r
++            public override System.Data.Linq.Mapping.MappingSource MappingSource\r
++            {\r
++                get { return source; }\r
++            }\r
++\r
++            public override System.Type ProviderType\r
++            {\r
++                get { return GetTypeFromName(d.Provider); }\r
++            }\r
++\r
++            public override System.Data.Linq.Mapping.MetaFunction GetFunction(MethodInfo method)\r
++            {\r
++                foreach (var f in GetFunctions())\r
++                    if (f.Method == method)\r
++                        return f;\r
++                throw new ArgumentException(String.Format("Corresponding MetaFunction for method '{0}' was not found", method));\r
++            }\r
++\r
++            public override IEnumerable<System.Data.Linq.Mapping.MetaFunction> GetFunctions()\r
++            {\r
++                if (functions == null)\r
++                {\r
++                    var l = new List<System.Data.Linq.Mapping.MetaFunction>();\r
++                    foreach (var f in d.Functions)\r
++                        l.Add(new XmlMetaFunction(this, f));\r
++                    functions = l.ToArray();\r
++                }\r
++                return functions;\r
++            }\r
++\r
++            public System.Type GetTypeFromName(string name)\r
++            {\r
++                string ns = context_type.Namespace;\r
++                string full = !name.Contains('.') && !String.IsNullOrEmpty(ns) ? String.Concat(ns, ".", name) : name;\r
++                var t = this.context_type.Assembly.GetType(full);\r
++                if (t == null)\r
++                    throw new ArgumentException(String.Format("Type '{0}' was not found", full));\r
++                return t;\r
++            }\r
++\r
++            public override System.Data.Linq.Mapping.MetaType GetMetaType(System.Type type)\r
++            {\r
++                if (!types.ContainsKey(type))\r
++                    throw new ArgumentException(String.Format("Type '{0}' is not found in the mapping", type));\r
++                return types[type];\r
++            }\r
++\r
++            public override System.Data.Linq.Mapping.MetaTable GetTable(System.Type rowType)\r
++            {\r
++                foreach (var t in GetTables())\r
++                    if (t.RowType.Type == rowType)\r
++                        return t;\r
++                //throw new ArgumentException(String.Format("Corresponding MetaTable for row type '{0}' was not found", rowType));\r
++                return null;\r
++            }\r
++\r
++            public override IEnumerable<System.Data.Linq.Mapping.MetaTable> GetTables()\r
++            {\r
++                if (tables == null)\r
++                {\r
++                    var l = new List<System.Data.Linq.Mapping.MetaTable>();\r
++                    foreach (var t in d.Tables)\r
++                        l.Add(new XmlMetaTable(this, t));\r
++                    tables = l.ToArray();\r
++                }\r
++                return tables;\r
++            }\r
++        }\r
++\r
++        class XmlMetaParameter : System.Data.Linq.Mapping.MetaParameter\r
++        {\r
++            string dbtype, mapped_name;\r
++            ParameterInfo pi;\r
++\r
++            public XmlMetaParameter(DbmlParameter p, ParameterInfo parameterInfo)\r
++                : this(p.DbType, p.Parameter, parameterInfo)\r
++            {\r
++            }\r
++\r
++            public XmlMetaParameter(string dbType, string mappedName, ParameterInfo parameterInfo)\r
++            {\r
++                this.dbtype = dbType;\r
++                this.mapped_name = mappedName;\r
++                this.pi = parameterInfo;\r
++            }\r
++\r
++            public override string DbType { get { return dbtype; } }\r
++            public override string MappedName { get { return mapped_name; } }\r
++            public override string Name { get { return Parameter.Name; } }\r
++            public override ParameterInfo Parameter { get { return pi; } }\r
++            public override System.Type ParameterType { get { return pi.ParameterType; } }\r
++        }\r
++\r
++        class XmlMetaTable : System.Data.Linq.Mapping.MetaTable\r
++        {\r
++            public XmlMetaTable(XmlMetaModel model, DbmlTable table)\r
++            {\r
++                this.model = model;\r
++                this.t = table;\r
++                foreach (var member in model.ContextType.GetMember(t.Member))\r
++                {\r
++                    if (table_member != null)\r
++                        throw new ArgumentException(String.Format("The context type '{0}' contains non-identical member '{1}'", model.ContextType, t.Member));\r
++                    table_member = member;\r
++                }\r
++                if (table_member == null)\r
++                    table_member = GetFieldsAndProperties(model.ContextType).First(pi => pi.GetMemberType().IsGenericType &&\r
++                        pi.GetMemberType().GetGenericTypeDefinition() == typeof(Table<>) &&\r
++                        pi.GetMemberType().GetGenericArguments()[0] == model.GetTypeFromName(t.Type.Name));\r
++                if (table_member == null)\r
++                    throw new ArgumentException(String.Format("The context type '{0}' does not contain member '{1}' which is specified in dbml", model.ContextType, t.Member));\r
++                member_type = table_member.GetMemberType();\r
++                if (member_type.GetGenericTypeDefinition() != typeof(Table<>))\r
++                    throw new ArgumentException(String.Format("The table member type was unexpected: '{0}'", member_type));\r
++                var rt = member_type.GetGenericArguments()[0];\r
++                row_type = model.GetMetaType(rt);\r
++                if (row_type == null)\r
++                    throw new ArgumentException(String.Format("MetaType for '{0}' was not found", rt));\r
++            }\r
++            static IEnumerable<MemberInfo> GetFieldsAndProperties(System.Type type)\r
++            {\r
++                foreach (var f in type.GetFields())\r
++                    yield return f;\r
++                foreach (var p in type.GetProperties())\r
++                    yield return p;\r
++            }\r
++\r
++            XmlMetaModel model;\r
++            DbmlTable t;\r
++            MemberInfo table_member;\r
++            System.Type member_type;\r
++            System.Data.Linq.Mapping.MetaType row_type;\r
++\r
++            [DbLinqToDo]\r
++            public override MethodInfo DeleteMethod\r
++            {\r
++                get { throw new NotImplementedException(); }\r
++            }\r
++            [DbLinqToDo]\r
++            public override MethodInfo InsertMethod\r
++            {\r
++                get { throw new NotImplementedException(); }\r
++            }\r
++            public override System.Data.Linq.Mapping.MetaModel Model { get { return model; } }\r
++            public override System.Data.Linq.Mapping.MetaType RowType { get { return row_type; } }\r
++            System.Type MemberType { get { return member_type; } }\r
++            public override string TableName { get { return t.Name; } }\r
++            [DbLinqToDo]\r
++            public override MethodInfo UpdateMethod\r
++            {\r
++                get { throw new NotImplementedException(); }\r
++            }\r
++\r
++            // not used yet\r
++            MethodInfo GetMethod(TableFunction f)\r
++            {\r
++                if (f == null)\r
++                    return null;\r
++                foreach (var mf in model.GetFunctions())\r
++                    if (mf.Name == f.FunctionId)\r
++                        return mf.Method;\r
++                return null;\r
++            }\r
++        }\r
++\r
++        class XmlMetaType : System.Data.Linq.Mapping.MetaType\r
++        {\r
++            XmlMetaModel model;\r
++            DbmlType t;\r
++            ReadOnlyCollection<System.Data.Linq.Mapping.MetaAssociation> associations;\r
++            System.Type runtime_type;\r
++            ReadOnlyCollection<System.Data.Linq.Mapping.MetaDataMember> members, identity_members, persistent_members;\r
++\r
++            public XmlMetaType(XmlMetaModel model, DbmlType type)\r
++            {\r
++                this.model = model;\r
++                this.t = type;\r
++                runtime_type = model.GetTypeFromName(t.Name);\r
++                int i = 0;\r
++                var l = new List<System.Data.Linq.Mapping.MetaDataMember>();\r
++                l.AddRange(Array.ConvertAll<DbmlColumn, System.Data.Linq.Mapping.MetaDataMember>(\r
++                    t.Columns.ToArray(), c => new XmlColumnMetaDataMember(model, this, c, i++)));\r
++                members = new ReadOnlyCollection<System.Data.Linq.Mapping.MetaDataMember>(l);\r
++            }\r
++\r
++            public override ReadOnlyCollection<System.Data.Linq.Mapping.MetaAssociation> Associations\r
++            {\r
++                get\r
++                {\r
++                    if (associations == null)\r
++                    {\r
++                        var l = new List<System.Data.Linq.Mapping.MetaAssociation>();\r
++                        // FIXME: Ordinal?\r
++                        foreach (var a in t.Associations)\r
++                            l.Add(new XmlMetaAssociation(this, new XmlAssociationMetaDataMember(model, this, a, -1), a));\r
++                        associations = new ReadOnlyCollection<System.Data.Linq.Mapping.MetaAssociation>(l.ToArray());\r
++                    }\r
++                    return associations;\r
++                }\r
++            }\r
++            public override bool CanInstantiate { get { return !runtime_type.IsAbstract; } }\r
++            public override ReadOnlyCollection<System.Data.Linq.Mapping.MetaDataMember> DataMembers { get { return members; } }\r
++            public override System.Data.Linq.Mapping.MetaDataMember DBGeneratedIdentityMember\r
++            {\r
++                get { return members.First(m => m.IsDbGenerated && m.IsPrimaryKey); }\r
++            }\r
++            [DbLinqToDo]\r
++            public override ReadOnlyCollection<System.Data.Linq.Mapping.MetaType> DerivedTypes\r
++            {\r
++                get { throw new NotImplementedException(); }\r
++            }\r
++            public override System.Data.Linq.Mapping.MetaDataMember Discriminator\r
++            {\r
++                get { return members.First(m => m.IsDiscriminator); }\r
++            }\r
++            public override bool HasAnyLoadMethod\r
++            {\r
++                get { return members.Any(m => m.LoadMethod != null); }\r
++            }\r
++            [DbLinqToDo]\r
++            public override bool HasAnyValidateMethod\r
++            {\r
++                get { throw new NotImplementedException(); }\r
++            }\r
++            [DbLinqToDo]\r
++            public override bool HasInheritance\r
++            {\r
++                get { throw new NotImplementedException(); }\r
++            }\r
++            public override bool HasInheritanceCode\r
++            {\r
++                get { return t.InheritanceCode != null; }\r
++            }\r
++            public override bool HasUpdateCheck { get { return members.Any(m => m.UpdateCheck != System.Data.Linq.Mapping.UpdateCheck.Never); } }\r
++            public override ReadOnlyCollection<System.Data.Linq.Mapping.MetaDataMember> IdentityMembers\r
++            {\r
++                get\r
++                {\r
++                    if (identity_members == null)\r
++                    {\r
++                        identity_members = new ReadOnlyCollection<System.Data.Linq.Mapping.MetaDataMember>(\r
++                            members.TakeWhile(m => m.IsPrimaryKey).ToArray());\r
++                    }\r
++                    return identity_members;\r
++                }\r
++            }\r
++            [DbLinqToDo]\r
++            public override System.Data.Linq.Mapping.MetaType InheritanceBase\r
++            {\r
++                get { throw new NotImplementedException(); }\r
++            }\r
++            public override Object InheritanceCode { get { return t.InheritanceCode; } }\r
++            [DbLinqToDo]\r
++            public override System.Data.Linq.Mapping.MetaType InheritanceDefault\r
++            {\r
++                get { throw new NotImplementedException(); }\r
++            }\r
++            [DbLinqToDo]\r
++            public override System.Data.Linq.Mapping.MetaType InheritanceRoot\r
++            {\r
++                get { throw new NotImplementedException(); }\r
++            }\r
++            [DbLinqToDo]\r
++            public override ReadOnlyCollection<System.Data.Linq.Mapping.MetaType> InheritanceTypes\r
++            {\r
++                get { throw new NotImplementedException(); }\r
++            }\r
++            [DbLinqToDo]\r
++            public override bool IsEntity { get { return true; } }\r
++            public override bool IsInheritanceDefault { get { return t.IsInheritanceDefault; } }\r
++            public override System.Data.Linq.Mapping.MetaModel Model { get { return model; } }\r
++            public override string Name { get { return t.Name; } }\r
++            [DbLinqToDo]\r
++            public override MethodInfo OnLoadedMethod\r
++            {\r
++                get { throw new NotImplementedException(); }\r
++            }\r
++            [DbLinqToDo]\r
++            public override MethodInfo OnValidateMethod\r
++            {\r
++                get { throw new NotImplementedException(); }\r
++            }\r
++            public override ReadOnlyCollection<System.Data.Linq.Mapping.MetaDataMember> PersistentDataMembers\r
++            {\r
++                get\r
++                {\r
++                    if (persistent_members == null)\r
++                    {\r
++                        persistent_members = new ReadOnlyCollection<System.Data.Linq.Mapping.MetaDataMember>(\r
++                            members.TakeWhile(m => m.IsPersistent).ToArray());\r
++                    }\r
++                    return persistent_members;\r
++                }\r
++            }\r
++            public override System.Data.Linq.Mapping.MetaTable Table { get { return model.GetTable(runtime_type); } }\r
++            public override System.Type Type { get { return runtime_type; } }\r
++            public override System.Data.Linq.Mapping.MetaDataMember VersionMember { get { return members.First(m => m.IsVersion); } }\r
++\r
++            public override System.Data.Linq.Mapping.MetaDataMember GetDataMember(MemberInfo member)\r
++            {\r
++                //return members.First(m => m.Member == member);\r
++                foreach (var m in members) if (m.Member == member) return m;\r
++                throw new ArgumentException(String.Format("No corresponding metadata member for '{0}'", member));\r
++            }\r
++\r
++            public override System.Data.Linq.Mapping.MetaType GetInheritanceType(System.Type type)\r
++            {\r
++                return InheritanceTypes.First(t => t.Type == type);\r
++            }\r
++\r
++            [DbLinqToDo]\r
++            public override System.Data.Linq.Mapping.MetaType GetTypeForInheritanceCode(object code)\r
++            {\r
++                throw new NotImplementedException();\r
++            }\r
++        }\r
++\r
++        class XmlMetaAssociation : System.Data.Linq.Mapping.MetaAssociation\r
++        {\r
++            //XmlMetaType owner;\r
++            DbmlAssociation a;\r
++            ReadOnlyCollection<System.Data.Linq.Mapping.MetaDataMember> these_keys, other_keys;\r
++            System.Data.Linq.Mapping.MetaDataMember member;\r
++\r
++            public XmlMetaAssociation(XmlMetaType owner, XmlMetaDataMember member, DbmlAssociation a)\r
++            {\r
++                //this.owner = owner;\r
++                this.member = member;\r
++                this.a = a;\r
++                SetupRelationship();\r
++            }\r
++\r
++            /// <summary>\r
++            /// This function sets up the relationship information based on the attribute <see cref="XmlMetaModel"/>.\r
++            /// </summary>\r
++            private void SetupRelationship()\r
++            {\r
++                //Get the association target type\r
++                System.Type targetType = member.Member.GetFirstInnerReturnType();\r
++\r
++                var metaModel = ThisMember.DeclaringType.Model as XmlMetaModel;\r
++                if (metaModel == null)\r
++                {\r
++                    throw new InvalidOperationException("Internal Error: MetaModel is not a XmlMetaModel");\r
++                }\r
++\r
++                System.Data.Linq.Mapping.MetaTable otherTable = metaModel.GetTable(targetType);\r
++\r
++                //Setup "this key"\r
++                these_keys = GetKeys(a.ThisKey ?? String.Empty, ThisMember.DeclaringType);\r
++\r
++                //Setup other key\r
++                other_keys = GetKeys(a.OtherKey ?? String.Empty, otherTable.RowType);\r
++            }\r
++\r
++            //Seperator used for key lists\r
++            private static readonly char[] STRING_SEPERATOR = new[] { ',' };\r
++\r
++            /// <summary>\r
++            /// Returns a list of keys from the given meta type based on the key list string.\r
++            /// </summary>\r
++            /// <param name="keyListString">The key list string.</param>\r
++            /// <param name="parentType">Type of the parent.</param>\r
++            /// <returns></returns>\r
++            private static ReadOnlyCollection<System.Data.Linq.Mapping.MetaDataMember> GetKeys(string keyListString, System.Data.Linq.Mapping.MetaType parentType)\r
++            {\r
++                if (keyListString != null)\r
++                {\r
++                    var thisKeyList = new List<System.Data.Linq.Mapping.MetaDataMember>();\r
++\r
++                    string[] keyNames = keyListString.Split(STRING_SEPERATOR, StringSplitOptions.RemoveEmptyEntries);\r
++\r
++                    foreach (string rawKeyName in keyNames)\r
++                    {\r
++                        string keyName = rawKeyName.Trim();\r
++\r
++                        //TODO: maybe speed the lookup up\r
++                        System.Data.Linq.Mapping.MetaDataMember key = (from dataMember in parentType.PersistentDataMembers\r
++                                              where dataMember.Name == keyName\r
++                                              select dataMember).SingleOrDefault();\r
++\r
++                        if (key == null)\r
++                        {\r
++                            string errorMessage = string.Format("Could not find key member '{0}' of key '{1}' on type '{2}'. The key may be wrong or the field or property on '{2}' has changed names.",\r
++                                keyName, keyListString, parentType.Type.Name);\r
++\r
++                            throw new InvalidOperationException(errorMessage);\r
++                        }\r
++\r
++                        thisKeyList.Add(key);\r
++                    }\r
++\r
++                    return new ReadOnlyCollection<System.Data.Linq.Mapping.MetaDataMember>(thisKeyList);\r
++                }\r
++                else //Key is the primary key of this table\r
++                {\r
++                    return parentType.IdentityMembers;\r
++                }\r
++            }\r
++\r
++            public override bool DeleteOnNull { get { return a.DeleteOnNull; } }\r
++            public override string DeleteRule { get { return a.DeleteRule; } }\r
++            public override bool IsForeignKey { get { return a.IsForeignKey; } }\r
++            [DbLinqToDo]\r
++            public override bool IsMany\r
++            {\r
++                get { throw new NotImplementedException(); }\r
++            }\r
++            public override bool IsNullable { get { return member.Member.GetMemberType().IsNullable(); } }\r
++            public override bool IsUnique { get { return a.IsUnique; } }\r
++            public override ReadOnlyCollection<System.Data.Linq.Mapping.MetaDataMember> OtherKey { get { return other_keys; } }\r
++            public override bool OtherKeyIsPrimaryKey { get { return OtherKey.All(m => m.IsPrimaryKey); } }\r
++            [DbLinqToDo]\r
++            public override System.Data.Linq.Mapping.MetaDataMember OtherMember\r
++            {\r
++                get { throw new NotImplementedException(); }\r
++            }\r
++            public override System.Data.Linq.Mapping.MetaType OtherType { get { return OtherMember.DeclaringType; } }\r
++            public override ReadOnlyCollection<System.Data.Linq.Mapping.MetaDataMember> ThisKey { get { return these_keys; } }\r
++            public override bool ThisKeyIsPrimaryKey { get { return ThisKey.All(m => m.IsPrimaryKey); } }\r
++            public override System.Data.Linq.Mapping.MetaDataMember ThisMember { get { return member; } }\r
++        }\r
++\r
++        abstract class XmlMetaDataMember : System.Data.Linq.Mapping.MetaDataMember\r
++        {\r
++            internal XmlMetaModel model;\r
++            internal XmlMetaType type;\r
++            internal MemberInfo member, storage;\r
++            System.Data.Linq.Mapping.MetaAccessor member_accessor, storage_accessor;\r
++            int ordinal;\r
++\r
++            protected XmlMetaDataMember(XmlMetaModel model, XmlMetaType type, string memberName, string storageName, int ordinal)\r
++            {\r
++                this.model = model;\r
++                this.type = type;\r
++                BindingFlags bf = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance;\r
++                if (type.Type.GetMember(memberName, bf).Length == 0)\r
++                    throw new ArgumentException(String.Format("Specified member '{0}' was not found in type '{1}'", memberName, type.Name));\r
++                if (type.Type.GetMember(storageName, bf).Length == 0)\r
++                    throw new ArgumentException(String.Format("Specified member '{0}' was not found in type '{1}'", storageName, type.Name));\r
++                this.member = type.Type.GetMember(memberName, bf)[0];\r
++                this.storage = type.Type.GetMember(storageName, bf)[0];\r
++                this.ordinal = ordinal;\r
++            }\r
++\r
++            public override bool CanBeNull { get { return member.GetMemberType().IsNullable(); } }\r
++            public override System.Data.Linq.Mapping.MetaType DeclaringType { get { return type; } }\r
++            public override bool IsDeferred { get { return false; } }\r
++            public override bool IsPersistent { get { return true; } }\r
++            public override MemberInfo Member { get { return member; } }\r
++            public override System.Data.Linq.Mapping.MetaAccessor MemberAccessor\r
++            {\r
++                get\r
++                {\r
++                    if (member_accessor == null)\r
++                        member_accessor = new XmlMetaAccessor(this, Member);\r
++                    return member_accessor;\r
++                }\r
++            }\r
++            public override int Ordinal { get { return ordinal; } }\r
++            public override System.Data.Linq.Mapping.MetaAccessor StorageAccessor\r
++            {\r
++                get\r
++                {\r
++                    if (storage_accessor == null)\r
++                        storage_accessor = new XmlMetaAccessor(this, StorageMember);\r
++                    return storage_accessor;\r
++                }\r
++            }\r
++            public override MemberInfo StorageMember { get { return storage; } }\r
++            public override System.Type Type { get { return member.GetMemberType(); } }\r
++\r
++            public override bool IsDeclaredBy(System.Data.Linq.Mapping.MetaType type)\r
++            {\r
++                return this.type == type;\r
++            }\r
++        }\r
++\r
++        class XmlColumnMetaDataMember : XmlMetaDataMember\r
++        {\r
++            DbmlColumn c;\r
++\r
++            public XmlColumnMetaDataMember(XmlMetaModel model, XmlMetaType type, DbmlColumn column, int ordinal)\r
++                : base(model, type, column.Member, column.Storage, ordinal)\r
++            {\r
++                this.c = column;\r
++            }\r
++\r
++            public override System.Data.Linq.Mapping.MetaAssociation Association { get { return null; } }\r
++            public override System.Data.Linq.Mapping.AutoSync AutoSync { get { return (System.Data.Linq.Mapping.AutoSync)c.AutoSync; } }\r
++            public override string DbType { get { return c.DbType; } }\r
++            [DbLinqToDo]\r
++            public override System.Data.Linq.Mapping.MetaAccessor DeferredSourceAccessor\r
++            {\r
++                get { throw new NotImplementedException(); }\r
++            }\r
++            [DbLinqToDo]\r
++            public override System.Data.Linq.Mapping.MetaAccessor DeferredValueAccessor\r
++            {\r
++                get { throw new NotImplementedException(); }\r
++            }\r
++\r
++            public override string Expression { get { return c.Expression; } }\r
++            public override bool IsAssociation { get { return false; } }\r
++            public override bool IsDbGenerated { get { return c.IsDbGenerated; } }\r
++            public override bool IsDiscriminator { get { return c.IsDiscriminator; } }\r
++            public override bool IsPrimaryKey { get { return c.IsPrimaryKey; } }\r
++            public override bool IsVersion { get { return c.IsVersion; } }\r
++            [DbLinqToDo]\r
++            public override MethodInfo LoadMethod\r
++            {\r
++                get\r
++                {\r
++                    throw new NotImplementedException();\r
++                }\r
++            }\r
++            public override string MappedName { get { return c.Name; } }\r
++            public override string Name { get { return c.Name ?? c.Member; } }\r
++            public override System.Data.Linq.Mapping.UpdateCheck UpdateCheck { get { return c.UpdateCheck; } }\r
++        }\r
++\r
++        class XmlAssociationMetaDataMember : XmlMetaDataMember\r
++        {\r
++            DbmlAssociation a;\r
++            XmlMetaAssociation ma;\r
++\r
++            public XmlAssociationMetaDataMember(XmlMetaModel model, XmlMetaType type, DbmlAssociation association, int ordinal)\r
++                : base(model, type, association.Member, association.Storage, ordinal)\r
++            {\r
++                this.a = association;\r
++            }\r
++\r
++            public override System.Data.Linq.Mapping.MetaAssociation Association\r
++            {\r
++                get\r
++                {\r
++                    if (ma == null)\r
++                        this.ma = new XmlMetaAssociation(type, this, a);\r
++                    return ma;\r
++                }\r
++            }\r
++            public override System.Data.Linq.Mapping.AutoSync AutoSync { get { return System.Data.Linq.Mapping.AutoSync.Never; } }\r
++            public override string DbType { get { return String.Empty; } }\r
++            [DbLinqToDo]\r
++            public override System.Data.Linq.Mapping.MetaAccessor DeferredSourceAccessor\r
++            {\r
++                get { throw new NotImplementedException(); }\r
++            }\r
++            [DbLinqToDo]\r
++            public override System.Data.Linq.Mapping.MetaAccessor DeferredValueAccessor\r
++            {\r
++                get { throw new NotImplementedException(); }\r
++            }\r
++\r
++            public override string Expression { get { return String.Empty; } }\r
++            public override bool IsAssociation { get { return true; } }\r
++            public override bool IsDbGenerated { get { return false; } }\r
++            public override bool IsDiscriminator { get { return false; } }\r
++            [DbLinqToDo]\r
++            public override bool IsPrimaryKey\r
++            {\r
++                get { throw new NotImplementedException(); }\r
++            }\r
++            [DbLinqToDo]\r
++            public override bool IsVersion\r
++            {\r
++                get { throw new NotImplementedException(); }\r
++            }\r
++            [DbLinqToDo]\r
++            public override MethodInfo LoadMethod\r
++            {\r
++                get\r
++                {\r
++                    throw new NotImplementedException();\r
++                }\r
++            }\r
++            public override string MappedName { get { return a.Member; } }\r
++            public override string Name { get { return a.Name; } }\r
++            public override System.Data.Linq.Mapping.UpdateCheck UpdateCheck\r
++            {\r
++                get\r
++                {\r
++                    throw new NotImplementedException();\r
++                }\r
++            }\r
++        }\r
++\r
++        class XmlMetaAccessor : System.Data.Linq.Mapping.MetaAccessor\r
++        {\r
++            XmlMetaDataMember member;\r
++            MemberInfo member_info;\r
++\r
++            public XmlMetaAccessor(XmlMetaDataMember member, MemberInfo memberInfo)\r
++            {\r
++                this.member = member;\r
++                this.member_info = memberInfo;\r
++            }\r
++\r
++            public override System.Type Type\r
++            {\r
++                get { return member_info is FieldInfo ? ((FieldInfo)member_info).FieldType : ((PropertyInfo)member_info).PropertyType; }\r
++            }\r
++\r
++            [DbLinqToDo]\r
++            public override object GetBoxedValue(object instance)\r
++            {\r
++                throw new NotImplementedException();\r
++            }\r
++\r
++            [DbLinqToDo]\r
++            public override void SetBoxedValue(ref object instance, object value)\r
++            {\r
++                throw new NotImplementedException();\r
++            }\r
++        }\r
++\r
++        class XmlMetaFunction : System.Data.Linq.Mapping.MetaFunction\r
++        {\r
++            XmlMetaModel model;\r
++            DbmlFunction f;\r
++            MethodInfo method;\r
++            ReadOnlyCollection<System.Data.Linq.Mapping.MetaParameter> parameters;\r
++            ReadOnlyCollection<System.Data.Linq.Mapping.MetaType> result_types;\r
++            System.Data.Linq.Mapping.MetaParameter return_param;\r
++\r
++            public XmlMetaFunction(XmlMetaModel model, DbmlFunction function)\r
++            {\r
++                this.model = model;\r
++                this.f = function;\r
++                method = model.ContextType.GetMethod(function.Method);\r
++                return_param = new XmlMetaParameter(function.Return.DbType, String.Empty, method.ReturnParameter);\r
++            }\r
++\r
++            public override bool HasMultipleResults { get { return f.ElementTypes.Count > 0; } }\r
++            public override bool IsComposable { get { return f.IsComposable; } }\r
++            public override string MappedName { get { return f.Name; } }\r
++            public override MethodInfo Method { get { return method; } }\r
++            public override System.Data.Linq.Mapping.MetaModel Model { get { return model; } }\r
++            public override string Name { get { return f.Name; } }\r
++            public override ReadOnlyCollection<System.Data.Linq.Mapping.MetaParameter> Parameters\r
++            {\r
++                get\r
++                {\r
++                    if (parameters == null)\r
++                    {\r
++                        var l = new List<System.Data.Linq.Mapping.MetaParameter>();\r
++                        int i = 0;\r
++                        ParameterInfo[] mparams = method.GetParameters();\r
++                        foreach (var p in f.Parameters)\r
++                            l.Add(new XmlMetaParameter(p, mparams[i++]));\r
++                        parameters = new ReadOnlyCollection<System.Data.Linq.Mapping.MetaParameter>(l);\r
++                    }\r
++                    return parameters;\r
++                }\r
++            }\r
++            public override ReadOnlyCollection<System.Data.Linq.Mapping.MetaType> ResultRowTypes\r
++            {\r
++                get\r
++                {\r
++                    if (result_types == null)\r
++                    {\r
++                        var l = new List<System.Data.Linq.Mapping.MetaType>();\r
++                        foreach (var p in f.ElementTypes)\r
++                            l.Add(model.GetMetaType(model.GetTypeFromName(p.Name)));\r
++                        result_types = new ReadOnlyCollection<System.Data.Linq.Mapping.MetaType>(l.ToArray());\r
++                    }\r
++                    return result_types;\r
++                }\r
++            }\r
++            public override System.Data.Linq.Mapping.MetaParameter ReturnParameter { get { return return_param; } }\r
++        }\r
++    }\r
++}\r
index 5671991167e7ad02b726f4f4a8f354ed6e20d62c,5671991167e7ad02b726f4f4a8f354ed6e20d62c..51559329e6453a5efa92e91305c15a8493697ee1
@@@ -172,6 -172,6 +172,10 @@@ namespace DbLinq.Data.Linq.Sugar.Implem
  \r
          public IList<MemberInfo> GetEntitySetAssociations(Type type)\r
          {\r
++            // BUG: This is ignoring External Mappings from XmlMappingSource.\r
++\r
++            // TODO: Should be cached in a static thread safe cache.\r
++\r
              return type.GetProperties()\r
                  .Where(p => p.PropertyType.IsGenericType \r
                      && (p.PropertyType.GetGenericTypeDefinition() == typeof(System.Data.Linq.EntitySet<>) \r
  \r
          public IList<MemberInfo> GetEntityRefAssociations(Type type)\r
          {\r
--            return (from p in type.GetProperties()\r
--                    let associationAttribute = p.GetCustomAttributes(typeof(AssociationAttribute), true).FirstOrDefault() as AssociationAttribute\r
--                    let field = type.GetField(associationAttribute != null ? (associationAttribute.Storage ?? string.Empty) : string.Empty, BindingFlags.NonPublic | BindingFlags.Instance)\r
--                    where associationAttribute != null &&\r
--                             field != null &&\r
--                            field.FieldType.IsGenericType &&\r
--                            field.FieldType.GetGenericTypeDefinition() == typeof(System.Data.Linq.EntityRef<>)\r
--                    select p)\r
--                .Cast<MemberInfo>().ToList();\r
++            // BUG: This is ignoring External Mappings from XmlMappingSource.\r
++\r
++            // TODO: Should be cached in a static thread safe cache.\r
++\r
++            List<MemberInfo> associations = new List<MemberInfo>();\r
++            foreach (var p in type.GetProperties())\r
++            {\r
++                AssociationAttribute associationAttribute = p.GetCustomAttributes(typeof(AssociationAttribute), true).FirstOrDefault() as AssociationAttribute;\r
++                if (associationAttribute != null)\r
++                {\r
++                    FieldInfo field = type.GetField(associationAttribute.Storage, BindingFlags.NonPublic | BindingFlags.Instance);\r
++                    if (field != null && field.FieldType.IsGenericType &&\r
++#if MONO_STRICT\r
++                        field.FieldType.GetGenericTypeDefinition() == typeof(System.Data.Linq.EntityRef<>)\r
++#else\r
++                        field.FieldType.GetGenericTypeDefinition() == typeof(DbLinq.Data.Linq.EntityRef<>)\r
++#endif\r
++                        )\r
++                        associations.Add(p);\r
++                }\r
++            }\r
++            return associations;\r
          }\r
      }\r
  }\r
index dfb79d83fccf26ae9eac2ec6ac279462402d94fa,dfb79d83fccf26ae9eac2ec6ac279462402d94fa..484b810e3629d5df3bc673e4ad1941c3a168a472
@@@ -58,43 -58,43 +58,43 @@@ namespace DbLinq.Data.Linq.Sugar.Implem
          public virtual IEnumerable<T> Select<T>(SelectQuery selectQuery)\r
          {\r
              var rowObjectCreator = selectQuery.GetRowObjectCreator<T>();\r
--            Console.WriteLine("# rowObjectCreator={0}", rowObjectCreator.Method);\r
--            Console.WriteLine("# rowObjectCreator.Target={0}", rowObjectCreator.Target.GetType().FullName);\r
++\r
++            IList<T> results = new List<T>();\r
  \r
              // handle the special case where the query is empty, meaning we don't need the DB\r
              if (string.IsNullOrEmpty(selectQuery.Sql.ToString()))\r
              {\r
--                yield return rowObjectCreator(null, null);\r
--                yield break;\r
++                results.Add(rowObjectCreator(null, null));\r
              }\r
--\r
--            using (var dbCommand = selectQuery.GetCommand())\r
++            else\r
              {\r
--\r
--                // write query to log\r
--                selectQuery.DataContext.WriteLog(dbCommand.Command);\r
--\r
--                using (var reader = dbCommand.Command.ExecuteReader())\r
++                using (var dbCommand = selectQuery.GetCommand())\r
                  {\r
--                    while (reader.Read())\r
--                    {\r
--                        // someone told me one day this could happen (in SQLite)\r
--                        if (reader.FieldCount == 0)\r
--                            continue;\r
++                    // write query to log\r
++                    selectQuery.DataContext.WriteLog(dbCommand.Command);\r
  \r
--                        var row = rowObjectCreator(reader, selectQuery.DataContext._MappingContext);\r
--                        // the conditions to register and watch an entity are:\r
--                        // - not null (can this happen?)\r
--                        // - registered in the model\r
--                        if (row != null && selectQuery.DataContext.Mapping.GetTable(row.GetType()) != null)\r
++                    using (var reader = dbCommand.Command.ExecuteReader())\r
++                    {\r
++                        while (reader.Read())\r
                          {\r
--                            row = (T)selectQuery.DataContext.Register(row);\r
--                        }\r
++                            // someone told me one day this could happen (in SQLite)\r
++                            if (reader.FieldCount == 0)\r
++                                continue;\r
  \r
--                        yield return row;\r
++                            var row = rowObjectCreator(reader, selectQuery.DataContext._MappingContext);\r
++                            // the conditions to register and watch an entity are:\r
++                            // - not null (can this happen?)\r
++                            // - registered in the model\r
++                            if (row != null && selectQuery.DataContext.Mapping.GetTable(row.GetType()) != null)\r
++                            {\r
++                                row = (T)selectQuery.DataContext.Register(row);\r
++                            }\r
++                            results.Add(row);\r
++                        }\r
                      }\r
                  }\r
              }\r
++            return results;\r
          }\r
  \r
          /// <summary>\r
index a7cf6b882c331e9793be14e5407d1cdaac9ab49b,a7cf6b882c331e9793be14e5407d1cdaac9ab49b..e093acd42c64666ae7d92f70c853019f8d9d0bb7
@@@ -68,6 -68,6 +68,8 @@@
      <Compile Include="Data\Linq\DBLinqExtendedAttributte.cs" />\r
      <Compile Include="Data\Linq\EntityRef.cs" />\r
      <Compile Include="Data\Linq\EntitySet.cs" />\r
++    <Compile Include="Data\Linq\Implementation\DisabledEntityTracker.cs" />\r
++    <Compile Include="Data\Linq\Implementation\IEntityTracker.cs" />\r
      <Compile Include="Data\Linq\Implementation\EntityTrack.cs" />\r
      <Compile Include="Data\Linq\Implementation\EntityState.cs" />\r
      <Compile Include="Data\Linq\Implementation\EntityTracker.cs" />\r
@@@ -97,6 -97,6 +99,7 @@@
      <Compile Include="Data\Linq\Mapping\AttributedMetaType.cs" />\r
      <Compile Include="Data\Linq\Mapping\AttributeMappingSource.cs" />\r
      <Compile Include="Data\Linq\Mapping\MappingContext.cs" />\r
++    <Compile Include="Data\Linq\Mapping\XmlMappingSource.cs" />\r
      <Compile Include="Data\Linq\SqlClient\FirebirdProvider.cs" />\r
      <Compile Include="Data\Linq\SqlClient\Sql2005Provider.cs" />\r
      <Compile Include="Data\Linq\SqlClient\Sql2000Provider.cs" />\r
index 525cb061b52d0487d762fd2b4921acee66c809ac,525cb061b52d0487d762fd2b4921acee66c809ac..6a39dec9817a4c564bb3fbc96c4c13b0381ba4c6
      <Compile Include="Data\Linq\Identity\Implementation\IdentityReaderFactory.cs" />\r
      <Compile Include="Data\Linq\IExecuteResult.cs" />\r
      <Compile Include="Data\Linq\IMemberModificationHandler.cs" />\r
++    <Compile Include="Data\Linq\Implementation\DisabledEntityTracker.cs" />\r
      <Compile Include="Data\Linq\Implementation\EntityState.cs" />\r
      <Compile Include="Data\Linq\Implementation\EntityTrack.cs" />\r
      <Compile Include="Data\Linq\Implementation\EntityTracker.cs" />\r
++    <Compile Include="Data\Linq\Implementation\IEntityTracker.cs" />\r
      <Compile Include="Data\Linq\Implementation\MemberModificationHandler.cs" />\r
      <Compile Include="Data\Linq\Implementation\QueryProvider.cs" />\r
      <Compile Include="Data\Linq\Implementation\VendorProvider.cs" />\r
      <Compile Include="Data\Linq\Mapping\AttributedMetaType.cs" />\r
      <Compile Include="Data\Linq\Mapping\AttributeMappingSource.cs" />\r
      <Compile Include="Data\Linq\Mapping\MappingContext.cs" />\r
++    <Compile Include="Data\Linq\Mapping\XmlMappingSource.cs" />\r
      <Compile Include="Data\Linq\RefreshMode.cs" />\r
      <Compile Include="Data\Linq\SqlClient\FirebirdProvider.cs" />\r
      <Compile Include="Data\Linq\SqlClient\IngresProvider.cs" />\r
      <Compile Include="System.Data.Linq\System.Data.Linq.Mapping\ResultTypeAttribute.cs" />\r
      <Compile Include="System.Data.Linq\System.Data.Linq.Mapping\TableAttribute.cs" />\r
      <Compile Include="System.Data.Linq\System.Data.Linq.Mapping\UpdateCheck.cs" />\r
--    <Compile Include="System.Data.Linq\System.Data.Linq.Mapping\XmlMappingSource.cs" />\r
      <Compile Include="System.Data.Linq\System.Data.Linq.SqlClient.Implementation\ObjectMaterializer.cs" />\r
      <Compile Include="System.Data.Linq\System.Data.Linq.SqlClient\Sql2000Provider.cs" />\r
      <Compile Include="System.Data.Linq\System.Data.Linq.SqlClient\Sql2005Provider.cs" />\r
diff --cc mcs/class/System.Data.Linq/src/DbLinq/System.Data.Linq/System.Data.Linq.Mapping/XmlMappingSource.cs
index 40695c819eb33b6b94e9e0217c8441515328fa53,40695c819eb33b6b94e9e0217c8441515328fa53..0000000000000000000000000000000000000000
deleted file mode 100644,100644
+++ /dev/null
@@@ -1,1180 -1,1180 +1,0 @@@
--#region MIT license\r
--// \r
--// MIT license\r
--//\r
--// Copyright (c) 2007-2008 Jiri Moudry, Stefan Klinger\r
--// \r
--// Permission is hereby granted, free of charge, to any person obtaining a copy\r
--// of this software and associated documentation files (the "Software"), to deal\r
--// in the Software without restriction, including without limitation the rights\r
--// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell\r
--// copies of the Software, and to permit persons to whom the Software is\r
--// furnished to do so, subject to the following conditions:\r
--// \r
--// The above copyright notice and this permission notice shall be included in\r
--// all copies or substantial portions of the Software.\r
--// \r
--// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\r
--// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\r
--// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\r
--// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\r
--// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\r
--// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\r
--// THE SOFTWARE.\r
--// \r
--#endregion\r
--\r
--#region grammar\r
--/* ----------------\r
--default namespace = "http://schemas.microsoft.com/linqtosql/mapping/2007"\r
--grammar {\r
--\r
--start = element Database { Database }\r
--\r
--Database = {\r
--  element Table { Table }*,\r
--  element Function { Function }*,\r
--  attribute Name { text }?,\r
--  attribute Provider { text }?\r
--}\r
--\r
--Table = {\r
--  element Type { Type },\r
--  attribute Name { text }?,\r
--  attribute Member { text }?\r
--}\r
--\r
--Type = {\r
--  {\r
--    element Column { Column }* |\r
--    element Association { Association }*\r
--  }*,\r
--  element Type { Type }*,\r
--  attribute Name { text },\r
--  attribute InheritanceCode { text }?,\r
--  attribute IsInheritanceDefault { boolean }?\r
--}\r
--\r
--Column = {\r
--  attribute Name { text }?,\r
--  attribute Member { text },\r
--  attribute Storage { text }?,\r
--  attribute DbType { text }?,\r
--  attribute IsPrimaryKey { boolean }?,\r
--  attribute IsDbGenerated { boolean }?,\r
--  attribute CanBeNull { boolean }?,\r
--  attribute UpdateCheck { UpdateCheck }?,\r
--  attribute IsDiscriminator { boolean }?,\r
--  attribute Expression { text }?,\r
--  attribute IsVersion { boolean }?,\r
--  attribute AutoSync { AutoSync}?\r
--}\r
--\r
--Association = {\r
--  attribute Name { text }?,\r
--  attribute Member { text },\r
--  attribute Storage { text }?,\r
--  attribute ThisKey { text }?,\r
--  attribute OtherKey { text }?,\r
--  attribute IsForeignKey { boolean }?,\r
--  attribute IsUnique { boolean }?,\r
--  attribute DeleteRule { text }?,\r
--  attribute DeleteOnNull { boolean }?\r
--}\r
--\r
--Function = {\r
--  element Parameter { Parameter }*,\r
--  {\r
--    element ElementType { Type }* |\r
--    element Return { Return }\r
--  },\r
--  attribute Name { text }?,\r
--  attribute Method { text },\r
--  attribute IsComposable { boolean }?\r
--}\r
--\r
--Parameter = {\r
--  attribute Name { text }?,\r
--  attribute Parameter { text },\r
--  attribute DbType { text }?,\r
--  attribute Direction { ParameterDirection }?\r
--}\r
--\r
--Return = attribute DbType { text}?\r
--\r
--UpdateCheck = "Always" | "Never" | "WhenChanged"\r
--ParameterDirection = "In" | "Out" | "InOut"\r
--AutoSync = "Never" | "OnInsert" | "OnUpdate" | "Always" | "Default"\r
--\r
--}\r
------------------ */\r
--#endregion\r
--\r
--using System;\r
--using System.Collections.Generic;\r
--using System.Collections.ObjectModel;\r
--using System.IO;\r
--using System.Linq;\r
--using System.Reflection;\r
--using System.Xml;\r
--using DbLinq;\r
--using DbLinq.Schema.Dbml;\r
--using DbLinq.Util;\r
--\r
--#if MONO_STRICT\r
--namespace System.Data.Linq.Mapping\r
--#else\r
--namespace DbLinq.Data.Linq.Mapping\r
--#endif\r
--{\r
--    public sealed class XmlMappingSource : MappingSource\r
--    {\r
--        DbmlDatabase db;\r
--\r
--        XmlMappingSource(XmlReader reader)\r
--        {\r
--            db = new DbmlDatabase(reader);\r
--        }\r
--\r
--        public static XmlMappingSource FromReader(XmlReader reader)\r
--        {\r
--            return new XmlMappingSource(reader);\r
--        }\r
--\r
--        public static XmlMappingSource FromStream(Stream stream)\r
--        {\r
--            return FromReader(XmlReader.Create(stream));\r
--        }\r
--\r
--        public static XmlMappingSource FromUrl(string url)\r
--        {\r
--            return FromReader(XmlReader.Create(url));\r
--        }\r
--\r
--        public static XmlMappingSource FromXml(string xml)\r
--        {\r
--            return FromReader(XmlReader.Create(new StringReader(xml)));\r
--        }\r
--\r
--        protected override MetaModel CreateModel(Type dataContextType)\r
--        {\r
--            return new XmlMetaModel(this, db, dataContextType);\r
--        }\r
--\r
--\r
--        abstract class DbmlItem\r
--        {\r
--            public const string DbmlNamespace = "http://schemas.microsoft.com/linqtosql/mapping/2007";\r
--\r
--            public void ReadEmptyContent(XmlReader r, string name)\r
--            {\r
--                if (r.IsEmptyElement)\r
--                    r.ReadStartElement(name, DbmlNamespace);\r
--                else\r
--                {\r
--                    r.ReadStartElement(name, DbmlNamespace);\r
--                    for (r.MoveToContent(); r.NodeType != XmlNodeType.EndElement; r.MoveToContent())\r
--                    {\r
--                        if (r.NamespaceURI != DbmlNamespace)\r
--                            r.Skip();\r
--                        throw UnexpectedItemError(r);\r
--                    }\r
--                    r.ReadEndElement();\r
--                }\r
--            }\r
--            public bool GetBooleanAttribute(XmlReader r, string attributeName)\r
--            {\r
--                return r.GetAttribute(attributeName) == "true";\r
--            }\r
--            public UpdateCheck GetUpdateCheckAttribute(XmlReader r, string attributeName)\r
--            {\r
--                var s = r.GetAttribute(attributeName);\r
--                return s != null ? (UpdateCheck)Enum.Parse(typeof(UpdateCheck), s) : default(UpdateCheck);\r
--            }\r
--            public AutoSync GetAutoSyncAttribute(XmlReader r, string attributeName)\r
--            {\r
--                var s = r.GetAttribute(attributeName);\r
--                return s != null ? (AutoSync)Enum.Parse(typeof(AutoSync), s) : default(AutoSync);\r
--            }\r
--            public T GetEnumAttribute<T>(XmlReader r, string attributeName)\r
--            {\r
--                var s = r.GetAttribute(attributeName);\r
--                return s != null ? (T)Enum.Parse(typeof(T), s) : default(T);\r
--            }\r
--            public XmlException UnexpectedItemError(XmlReader r)\r
--            {\r
--                return new XmlException(String.Format("Unexpected dbml element '{0}'", r.LocalName));\r
--            }\r
--        }\r
--        class DbmlDatabase : DbmlItem\r
--        {\r
--            public string Name;\r
--            public string Provider;\r
--            public List<DbmlTable> Tables = new List<DbmlTable>();\r
--            public List<DbmlFunction> Functions = new List<DbmlFunction>();\r
--\r
--            public DbmlDatabase(XmlReader r)\r
--            {\r
--                r.MoveToContent();\r
--                Name = r.GetAttribute("Name");\r
--                Provider = r.GetAttribute("Provider");\r
--                if (r.IsEmptyElement)\r
--                    r.ReadStartElement("Database", DbmlNamespace);\r
--                else\r
--                {\r
--                    r.ReadStartElement("Database", DbmlNamespace);\r
--                    for (r.MoveToContent(); r.NodeType != XmlNodeType.EndElement; r.MoveToContent())\r
--                    {\r
--                        if (r.NamespaceURI != DbmlNamespace)\r
--                            r.Skip();\r
--                        else\r
--                        {\r
--                            switch (r.LocalName)\r
--                            {\r
--                                case "Table":\r
--                                    Tables.Add(new DbmlTable(r));\r
--                                    break;\r
--                                case "Function":\r
--                                    Functions.Add(new DbmlFunction(r));\r
--                                    break;\r
--                                default:\r
--                                    throw UnexpectedItemError(r);\r
--                            }\r
--                        }\r
--                    }\r
--                    r.ReadEndElement();\r
--                }\r
--            }\r
--        }\r
--        class DbmlTable : DbmlItem\r
--        {\r
--            public DbmlType Type;\r
--            public string Name;\r
--            public string Member;\r
--\r
--            public DbmlTable(XmlReader r)\r
--            {\r
--                Name = r.GetAttribute("Name");\r
--                Member = r.GetAttribute("Member");\r
--                if (r.IsEmptyElement)\r
--                    r.ReadStartElement("Table", DbmlNamespace);\r
--                else\r
--                {\r
--                    r.ReadStartElement("Table", DbmlNamespace);\r
--                    for (r.MoveToContent(); r.NodeType != XmlNodeType.EndElement; r.MoveToContent())\r
--                    {\r
--                        if (r.NamespaceURI != DbmlNamespace)\r
--                            r.Skip();\r
--                        else\r
--                        {\r
--                            switch (r.LocalName)\r
--                            {\r
--                                case "Type":\r
--                                    Type = new DbmlType(r);\r
--                                    break;\r
--                                default:\r
--                                    throw UnexpectedItemError(r);\r
--                            }\r
--                        }\r
--                    }\r
--                    r.ReadEndElement();\r
--                }\r
--            }\r
--        }\r
--        class DbmlType : DbmlItem\r
--        {\r
--            public List<DbmlColumn> Columns = new List<DbmlColumn>();\r
--            public List<DbmlAssociation> Associations = new List<DbmlAssociation>();\r
--            public List<DbmlType> Types = new List<DbmlType>();\r
--            public string Name;\r
--            public string InheritanceCode;\r
--            public bool IsInheritanceDefault;\r
--\r
--            public DbmlType(XmlReader r)\r
--            {\r
--                Name = r.GetAttribute("Name");\r
--                InheritanceCode = r.GetAttribute("InheritanceCode");\r
--                IsInheritanceDefault = GetBooleanAttribute(r, "IsInheritanceDefault");\r
--                if (r.IsEmptyElement)\r
--                    r.ReadStartElement("Type", DbmlNamespace);\r
--                else\r
--                {\r
--                    r.ReadStartElement("Type", DbmlNamespace);\r
--                    for (r.MoveToContent(); r.NodeType != XmlNodeType.EndElement; r.MoveToContent())\r
--                    {\r
--                        if (r.NamespaceURI != DbmlNamespace)\r
--                            r.Skip();\r
--                        else\r
--                        {\r
--                            switch (r.LocalName)\r
--                            {\r
--                                case "Column":\r
--                                    Columns.Add(new DbmlColumn(r));\r
--                                    break;\r
--                                case "Association":\r
--                                    Associations.Add(new DbmlAssociation(r));\r
--                                    break;\r
--                                case "Type":\r
--                                    Types.Add(new DbmlType(r));\r
--                                    break;\r
--                                default:\r
--                                    throw UnexpectedItemError(r);\r
--                            }\r
--                        }\r
--                    }\r
--                    r.ReadEndElement();\r
--                }\r
--            }\r
--        }\r
--\r
--        class DbmlMemberBase : DbmlItem\r
--        {\r
--            public string Name;\r
--            public string Member;\r
--            public string Storage;\r
--        }\r
--\r
--        class DbmlColumn : DbmlMemberBase\r
--        {\r
--            public string DbType;\r
--            public bool IsPrimaryKey;\r
--            public bool IsDbGenerated;\r
--            public bool CanBeNull;\r
--            public UpdateCheck UpdateCheck;\r
--            public bool IsDiscriminator;\r
--            public string Expression;\r
--            public bool IsVersion;\r
--            public AutoSync AutoSync;\r
--\r
--            public DbmlColumn(XmlReader r)\r
--            {\r
--                Member = r.GetAttribute("Member");\r
--                Name = r.GetAttribute("Name") ?? Member;\r
--                Storage = r.GetAttribute("Storage");\r
--                DbType = r.GetAttribute("DbType");\r
--                IsPrimaryKey = GetBooleanAttribute(r, "IsPrimaryKey");\r
--                IsDbGenerated = GetBooleanAttribute(r, "IsDbGenerated");\r
--                CanBeNull = GetBooleanAttribute(r, "CanBeNull");\r
--                UpdateCheck = GetEnumAttribute<UpdateCheck>(r, "UpdateCheck");\r
--                IsDiscriminator = GetBooleanAttribute(r, "IsDiscriminator");\r
--                Expression = r.GetAttribute("Expression");\r
--                IsVersion = GetBooleanAttribute(r, "IsVersion");\r
--                AutoSync = GetEnumAttribute<AutoSync>(r, "AutoSync");\r
--                ReadEmptyContent(r, "Column");\r
--            }\r
--        }\r
--        class DbmlAssociation : DbmlMemberBase\r
--        {\r
--            public string ThisKey;\r
--            public string OtherKey;\r
--            public bool IsForeignKey;\r
--            public bool IsUnique;\r
--            public string DeleteRule;\r
--            public bool DeleteOnNull;\r
--\r
--            public DbmlAssociation(XmlReader r)\r
--            {\r
--                Name = r.GetAttribute("Name");\r
--                Member = r.GetAttribute("Member");\r
--                Storage = r.GetAttribute("Storage");\r
--                ThisKey = r.GetAttribute("ThisKey");\r
--                OtherKey = r.GetAttribute("OtherKey");\r
--                IsForeignKey = GetBooleanAttribute(r, "IsForeignKey");\r
--                IsUnique = GetBooleanAttribute(r, "IsUnique");\r
--                DeleteRule = r.GetAttribute("DeleteRule");\r
--                DeleteOnNull = GetBooleanAttribute(r, "DeleteOnNull");\r
--                ReadEmptyContent(r, "Association");\r
--            }\r
--        }\r
--        class DbmlFunction : DbmlItem\r
--        {\r
--            public string Name;\r
--            public string Method;\r
--            public bool IsComposable;\r
--            public List<DbmlParameter> Parameters = new List<DbmlParameter>();\r
--            public List<DbmlType> ElementTypes = new List<DbmlType>();\r
--            public DbmlReturn Return;\r
--\r
--            public DbmlFunction(XmlReader r)\r
--            {\r
--                Name = r.GetAttribute("Name");\r
--                Method = r.GetAttribute("Method");\r
--                IsComposable = GetBooleanAttribute(r, "IsComposable");\r
--                if (r.IsEmptyElement)\r
--                    r.ReadStartElement("Function", DbmlNamespace);\r
--                else\r
--                {\r
--                    r.ReadStartElement("Function", DbmlNamespace);\r
--                    for (r.MoveToContent(); r.NodeType != XmlNodeType.EndElement; r.MoveToContent())\r
--                    {\r
--                        if (r.NamespaceURI != DbmlNamespace)\r
--                            r.Skip();\r
--                        else\r
--                        {\r
--                            switch (r.LocalName)\r
--                            {\r
--                                case "Parameter":\r
--                                    Parameters.Add(new DbmlParameter(r));\r
--                                    break;\r
--                                case "ElementType":\r
--                                    ElementTypes.Add(new DbmlType(r));\r
--                                    break;\r
--                                case "Return":\r
--                                    Return = new DbmlReturn(r);\r
--                                    break;\r
--                                default:\r
--                                    throw UnexpectedItemError(r);\r
--                            }\r
--                        }\r
--                    }\r
--                    r.ReadEndElement();\r
--                }\r
--            }\r
--        }\r
--        class DbmlParameter : DbmlItem\r
--        {\r
--            public string Name;\r
--            public string Parameter;\r
--            public string DbType;\r
--            public ParameterDirection Direction;\r
--\r
--            public DbmlParameter(XmlReader r)\r
--            {\r
--                Name = r.GetAttribute("Name");\r
--                Parameter = r.GetAttribute("Parameter");\r
--                DbType = r.GetAttribute("DbType");\r
--                Direction = GetEnumAttribute<ParameterDirection>(r, "Direction");\r
--                ReadEmptyContent(r, "Parameter");\r
--            }\r
--        }\r
--        class DbmlReturn : DbmlItem\r
--        {\r
--            public string DbType;\r
--\r
--            public DbmlReturn(XmlReader r)\r
--            {\r
--                DbType = r.GetAttribute("DbType");\r
--                ReadEmptyContent(r, "Return");\r
--            }\r
--        }\r
--\r
--        class XmlMetaModel : MetaModel\r
--        {\r
--            MappingSource source;\r
--            DbmlDatabase d;\r
--            Type context_type;\r
--            MetaFunction[] functions;\r
--            MetaTable[] tables;\r
--            Dictionary<Type, XmlMetaType> types;\r
--\r
--            public XmlMetaModel(MappingSource source, DbmlDatabase database, Type contextType)\r
--            {\r
--                this.source = source;\r
--                this.d = database;\r
--                this.context_type = contextType;\r
--                RegisterTypes();\r
--            }\r
--\r
--            void RegisterTypes()\r
--            {\r
--                types = new Dictionary<Type, XmlMetaType>();\r
--                foreach (var t in d.Tables)\r
--                    RegisterTypeAndDescendants(t.Type);\r
--            }\r
--\r
--            void RegisterTypeAndDescendants(DbmlType dt)\r
--            {\r
--\r
--                Type t = GetTypeFromName(dt.Name);\r
--                if (t == null)\r
--                    throw new ArgumentException(String.Format("type '{0}' not found", dt.Name));\r
--                if (types.ContainsKey(t))\r
--                    return;\r
--                types.Add(t, new XmlMetaType(this, dt));\r
--                foreach (var cdt in dt.Types)\r
--                    RegisterTypeAndDescendants(cdt);\r
--            }\r
--\r
--            public override Type ContextType\r
--            {\r
--                get { return context_type; }\r
--            }\r
--\r
--            public override string DatabaseName\r
--            {\r
--                get { return d.Name; }\r
--            }\r
--\r
--            public override MappingSource MappingSource\r
--            {\r
--                get { return source; }\r
--            }\r
--\r
--            public override Type ProviderType\r
--            {\r
--                get { return GetTypeFromName(d.Provider); }\r
--            }\r
--\r
--            public override MetaFunction GetFunction(MethodInfo method)\r
--            {\r
--                foreach (var f in GetFunctions())\r
--                    if (f.Method == method)\r
--                        return f;\r
--                throw new ArgumentException(String.Format("Corresponding MetaFunction for method '{0}' was not found", method));\r
--            }\r
--\r
--            public override IEnumerable<MetaFunction> GetFunctions()\r
--            {\r
--                if (functions == null)\r
--                {\r
--                    var l = new List<MetaFunction>();\r
--                    foreach (var f in d.Functions)\r
--                        l.Add(new XmlMetaFunction(this, f));\r
--                    functions = l.ToArray();\r
--                }\r
--                return functions;\r
--            }\r
--\r
--            public Type GetTypeFromName(string name)\r
--            {\r
--                string ns = context_type.Namespace;\r
--                string full = !name.Contains('.') && !String.IsNullOrEmpty(ns) ? String.Concat(ns, ".", name) : name;\r
--                var t = this.context_type.Assembly.GetType(full);\r
--                if (t == null)\r
--                    throw new ArgumentException(String.Format("Type '{0}' was not found", full));\r
--                return t;\r
--            }\r
--\r
--            public override MetaType GetMetaType(Type type)\r
--            {\r
--                if (!types.ContainsKey(type))\r
--                    throw new ArgumentException(String.Format("Type '{0}' is not found in the mapping", type));\r
--                return types[type];\r
--            }\r
--\r
--            public override MetaTable GetTable(Type rowType)\r
--            {\r
--                foreach (var t in GetTables())\r
--                    if (t.RowType.Type == rowType)\r
--                        return t;\r
--                //throw new ArgumentException(String.Format("Corresponding MetaTable for row type '{0}' was not found", rowType));\r
--                return null;\r
--            }\r
--\r
--            public override IEnumerable<MetaTable> GetTables()\r
--            {\r
--                if (tables == null)\r
--                {\r
--                    var l = new List<MetaTable>();\r
--                    foreach (var t in d.Tables)\r
--                        l.Add(new XmlMetaTable(this, t));\r
--                    tables = l.ToArray();\r
--                }\r
--                return tables;\r
--            }\r
--        }\r
--\r
--        class XmlMetaParameter : MetaParameter\r
--        {\r
--            string dbtype, mapped_name;\r
--            ParameterInfo pi;\r
--\r
--            public XmlMetaParameter(DbmlParameter p, ParameterInfo parameterInfo)\r
--                : this(p.DbType, p.Parameter, parameterInfo)\r
--            {\r
--            }\r
--\r
--            public XmlMetaParameter(string dbType, string mappedName, ParameterInfo parameterInfo)\r
--            {\r
--                this.dbtype = dbType;\r
--                this.mapped_name = mappedName;\r
--                this.pi = parameterInfo;\r
--            }\r
--\r
--            public override string DbType { get { return dbtype; } }\r
--            public override string MappedName { get { return mapped_name; } }\r
--            public override string Name { get { return Parameter.Name; } }\r
--            public override ParameterInfo Parameter { get { return pi; } }\r
--            public override Type ParameterType { get { return pi.ParameterType; } }\r
--        }\r
--\r
--        class XmlMetaTable : MetaTable\r
--        {\r
--            public XmlMetaTable(XmlMetaModel model, DbmlTable table)\r
--            {\r
--                this.model = model;\r
--                this.t = table;\r
--                foreach (var member in model.ContextType.GetMember(t.Member))\r
--                {\r
--                    if (table_member != null)\r
--                        throw new ArgumentException(String.Format("The context type '{0}' contains non-identical member '{1}'", model.ContextType, t.Member));\r
--                    table_member = member;\r
--                }\r
--                if (table_member == null)\r
--                    table_member = GetFieldsAndProperties(model.ContextType).First(pi => pi.GetMemberType().IsGenericType &&\r
--                        pi.GetMemberType().GetGenericTypeDefinition() == typeof(Table<>) &&\r
--                        pi.GetMemberType().GetGenericArguments()[0] == model.GetTypeFromName(t.Type.Name));\r
--                if (table_member == null)\r
--                    throw new ArgumentException(String.Format("The context type '{0}' does not contain member '{1}' which is specified in dbml", model.ContextType, t.Member));\r
--                member_type = table_member.GetMemberType();\r
--                if (member_type.GetGenericTypeDefinition() != typeof(Table<>))\r
--                    throw new ArgumentException(String.Format("The table member type was unexpected: '{0}'", member_type));\r
--                var rt = member_type.GetGenericArguments()[0];\r
--                row_type = model.GetMetaType(rt);\r
--                if (row_type == null)\r
--                    throw new ArgumentException(String.Format("MetaType for '{0}' was not found", rt));\r
--            }\r
--            static IEnumerable<MemberInfo> GetFieldsAndProperties(Type type)\r
--            {\r
--                foreach (var f in type.GetFields())\r
--                    yield return f;\r
--                foreach (var p in type.GetProperties())\r
--                    yield return p;\r
--            }\r
--\r
--            XmlMetaModel model;\r
--            DbmlTable t;\r
--            MemberInfo table_member;\r
--            Type member_type;\r
--            MetaType row_type;\r
--\r
--            [DbLinqToDo]\r
--            public override MethodInfo DeleteMethod\r
--            {\r
--                get { throw new NotImplementedException(); }\r
--            }\r
--            [DbLinqToDo]\r
--            public override MethodInfo InsertMethod\r
--            {\r
--                get { throw new NotImplementedException(); }\r
--            }\r
--            public override MetaModel Model { get { return model; } }\r
--            public override MetaType RowType { get { return row_type; } }\r
--            Type MemberType { get { return member_type; } }\r
--            public override string TableName { get { return t.Name; } }\r
--            [DbLinqToDo]\r
--            public override MethodInfo UpdateMethod\r
--            {\r
--                get { throw new NotImplementedException(); }\r
--            }\r
--\r
--            // not used yet\r
--            MethodInfo GetMethod(TableFunction f)\r
--            {\r
--                if (f == null)\r
--                    return null;\r
--                foreach (var mf in model.GetFunctions())\r
--                    if (mf.Name == f.FunctionId)\r
--                        return mf.Method;\r
--                return null;\r
--            }\r
--        }\r
--\r
--        class XmlMetaType : MetaType\r
--        {\r
--            XmlMetaModel model;\r
--            DbmlType t;\r
--            ReadOnlyCollection<MetaAssociation> associations;\r
--            Type runtime_type;\r
--            ReadOnlyCollection<MetaDataMember> members, identity_members, persistent_members;\r
--\r
--            public XmlMetaType(XmlMetaModel model, DbmlType type)\r
--            {\r
--                this.model = model;\r
--                this.t = type;\r
--                runtime_type = model.GetTypeFromName(t.Name);\r
--                int i = 0;\r
--                var l = new List<MetaDataMember>();\r
--                l.AddRange(Array.ConvertAll<DbmlColumn, MetaDataMember>(\r
--                    t.Columns.ToArray(), c => new XmlColumnMetaDataMember(model, this, c, i++)));\r
--                members = new ReadOnlyCollection<MetaDataMember>(l);\r
--            }\r
--\r
--            public override ReadOnlyCollection<MetaAssociation> Associations\r
--            {\r
--                get\r
--                {\r
--                    if (associations == null)\r
--                    {\r
--                        var l = new List<MetaAssociation>();\r
--                        // FIXME: Ordinal?\r
--                        foreach (var a in t.Associations)\r
--                            l.Add(new XmlMetaAssociation(this, new XmlAssociationMetaDataMember(model, this, a, -1), a));\r
--                        associations = new ReadOnlyCollection<MetaAssociation>(l.ToArray());\r
--                    }\r
--                    return associations;\r
--                }\r
--            }\r
--            public override bool CanInstantiate { get { return !runtime_type.IsAbstract; } }\r
--            public override ReadOnlyCollection<MetaDataMember> DataMembers { get { return members; } }\r
--            public override MetaDataMember DBGeneratedIdentityMember\r
--            {\r
--                get { return members.First(m => m.IsDbGenerated && m.IsPrimaryKey); }\r
--            }\r
--            [DbLinqToDo]\r
--            public override ReadOnlyCollection<MetaType> DerivedTypes\r
--            {\r
--                get { throw new NotImplementedException(); }\r
--            }\r
--            public override MetaDataMember Discriminator\r
--            {\r
--                get { return members.First(m => m.IsDiscriminator); }\r
--            }\r
--            public override bool HasAnyLoadMethod\r
--            {\r
--                get { return members.Any(m => m.LoadMethod != null); }\r
--            }\r
--            [DbLinqToDo]\r
--            public override bool HasAnyValidateMethod\r
--            {\r
--                get { throw new NotImplementedException(); }\r
--            }\r
--            [DbLinqToDo]\r
--            public override bool HasInheritance\r
--            {\r
--                get { throw new NotImplementedException(); }\r
--            }\r
--            public override bool HasInheritanceCode\r
--            {\r
--                get { return t.InheritanceCode != null; }\r
--            }\r
--            public override bool HasUpdateCheck { get { return members.Any(m => m.UpdateCheck != UpdateCheck.Never); } }\r
--            public override ReadOnlyCollection<MetaDataMember> IdentityMembers\r
--            {\r
--                get\r
--                {\r
--                    if (identity_members == null)\r
--                    {\r
--                        identity_members = new ReadOnlyCollection<MetaDataMember>(\r
--                            members.TakeWhile(m => m.IsPrimaryKey).ToArray());\r
--                    }\r
--                    return identity_members;\r
--                }\r
--            }\r
--            [DbLinqToDo]\r
--            public override MetaType InheritanceBase\r
--            {\r
--                get { throw new NotImplementedException(); }\r
--            }\r
--            public override Object InheritanceCode { get { return t.InheritanceCode; } }\r
--            [DbLinqToDo]\r
--            public override MetaType InheritanceDefault\r
--            {\r
--                get { throw new NotImplementedException(); }\r
--            }\r
--            [DbLinqToDo]\r
--            public override MetaType InheritanceRoot\r
--            {\r
--                get { throw new NotImplementedException(); }\r
--            }\r
--            [DbLinqToDo]\r
--            public override ReadOnlyCollection<MetaType> InheritanceTypes\r
--            {\r
--                get { throw new NotImplementedException(); }\r
--            }\r
--            [DbLinqToDo]\r
--            public override bool IsEntity { get { return true; } }\r
--            public override bool IsInheritanceDefault { get { return t.IsInheritanceDefault; } }\r
--            public override MetaModel Model { get { return model; } }\r
--            public override string Name { get { return t.Name; } }\r
--            [DbLinqToDo]\r
--            public override MethodInfo OnLoadedMethod\r
--            {\r
--                get { throw new NotImplementedException(); }\r
--            }\r
--            [DbLinqToDo]\r
--            public override MethodInfo OnValidateMethod\r
--            {\r
--                get { throw new NotImplementedException(); }\r
--            }\r
--            public override ReadOnlyCollection<MetaDataMember> PersistentDataMembers\r
--            {\r
--                get\r
--                {\r
--                    if (persistent_members == null)\r
--                    {\r
--                        persistent_members = new ReadOnlyCollection<MetaDataMember>(\r
--                            members.TakeWhile(m => m.IsPersistent).ToArray());\r
--                    }\r
--                    return persistent_members;\r
--                }\r
--            }\r
--            public override MetaTable Table { get { return model.GetTable(runtime_type); } }\r
--            public override Type Type { get { return runtime_type; } }\r
--            public override MetaDataMember VersionMember { get { return members.First(m => m.IsVersion); } }\r
--\r
--            public override MetaDataMember GetDataMember(MemberInfo member)\r
--            {\r
--                //return members.First(m => m.Member == member);\r
--                foreach (var m in members) if (m.Member == member) return m;\r
--                throw new ArgumentException(String.Format("No corresponding metadata member for '{0}'", member));\r
--            }\r
--\r
--            public override MetaType GetInheritanceType(Type type)\r
--            {\r
--                return InheritanceTypes.First(t => t.Type == type);\r
--            }\r
--\r
--            [DbLinqToDo]\r
--            public override MetaType GetTypeForInheritanceCode(object code)\r
--            {\r
--                throw new NotImplementedException();\r
--            }\r
--        }\r
--\r
--        class XmlMetaAssociation : MetaAssociation\r
--        {\r
--            //XmlMetaType owner;\r
--            DbmlAssociation a;\r
--            ReadOnlyCollection<MetaDataMember> these_keys, other_keys;\r
--            MetaDataMember member;\r
--\r
--            public XmlMetaAssociation(XmlMetaType owner, XmlMetaDataMember member, DbmlAssociation a)\r
--            {\r
--                //this.owner = owner;\r
--                this.member = member;\r
--                this.a = a;\r
--                SetupRelationship();\r
--            }\r
--\r
--            /// <summary>\r
--            /// This function sets up the relationship information based on the attribute <see cref="XmlMetaModel"/>.\r
--            /// </summary>\r
--            private void SetupRelationship()\r
--            {\r
--                //Get the association target type\r
--                Type targetType = member.Member.GetFirstInnerReturnType();\r
--\r
--                var metaModel = ThisMember.DeclaringType.Model as XmlMetaModel;\r
--                if (metaModel == null)\r
--                {\r
--                    throw new InvalidOperationException("Internal Error: MetaModel is not a XmlMetaModel");\r
--                }\r
--\r
--                MetaTable otherTable = metaModel.GetTable(targetType);\r
--\r
--                //Setup "this key"\r
--                these_keys = GetKeys(a.ThisKey ?? String.Empty, ThisMember.DeclaringType);\r
--\r
--                //Setup other key\r
--                other_keys = GetKeys(a.OtherKey ?? String.Empty, otherTable.RowType);\r
--            }\r
--\r
--            //Seperator used for key lists\r
--            private static readonly char[] STRING_SEPERATOR = new[] { ',' };\r
--\r
--            /// <summary>\r
--            /// Returns a list of keys from the given meta type based on the key list string.\r
--            /// </summary>\r
--            /// <param name="keyListString">The key list string.</param>\r
--            /// <param name="parentType">Type of the parent.</param>\r
--            /// <returns></returns>\r
--            private static ReadOnlyCollection<MetaDataMember> GetKeys(string keyListString, MetaType parentType)\r
--            {\r
--                if (keyListString != null)\r
--                {\r
--                    var thisKeyList = new List<MetaDataMember>();\r
--\r
--                    string[] keyNames = keyListString.Split(STRING_SEPERATOR, StringSplitOptions.RemoveEmptyEntries);\r
--\r
--                    foreach (string rawKeyName in keyNames)\r
--                    {\r
--                        string keyName = rawKeyName.Trim();\r
--\r
--                        //TODO: maybe speed the lookup up\r
--                        MetaDataMember key = (from dataMember in parentType.PersistentDataMembers\r
--                                              where dataMember.Name == keyName\r
--                                              select dataMember).SingleOrDefault();\r
--\r
--                        if (key == null)\r
--                        {\r
--                            string errorMessage = string.Format("Could not find key member '{0}' of key '{1}' on type '{2}'. The key may be wrong or the field or property on '{2}' has changed names.",\r
--                                keyName, keyListString, parentType.Type.Name);\r
--\r
--                            throw new InvalidOperationException(errorMessage);\r
--                        }\r
--\r
--                        thisKeyList.Add(key);\r
--                    }\r
--\r
--                    return new ReadOnlyCollection<MetaDataMember>(thisKeyList);\r
--                }\r
--                else //Key is the primary key of this table\r
--                {\r
--                    return parentType.IdentityMembers;\r
--                }\r
--            }\r
--\r
--            public override bool DeleteOnNull { get { return a.DeleteOnNull; } }\r
--            public override string DeleteRule { get { return a.DeleteRule; } }\r
--            public override bool IsForeignKey { get { return a.IsForeignKey; } }\r
--            [DbLinqToDo]\r
--            public override bool IsMany\r
--            {\r
--                get { throw new NotImplementedException(); }\r
--            }\r
--            public override bool IsNullable { get { return member.Member.GetMemberType().IsNullable(); } }\r
--            public override bool IsUnique { get { return a.IsUnique; } }\r
--            public override ReadOnlyCollection<MetaDataMember> OtherKey { get { return other_keys; } }\r
--            public override bool OtherKeyIsPrimaryKey { get { return OtherKey.All(m => m.IsPrimaryKey); } }\r
--            [DbLinqToDo]\r
--            public override MetaDataMember OtherMember\r
--            {\r
--                get { throw new NotImplementedException(); }\r
--            }\r
--            public override MetaType OtherType { get { return OtherMember.DeclaringType; } }\r
--            public override ReadOnlyCollection<MetaDataMember> ThisKey { get { return these_keys; } }\r
--            public override bool ThisKeyIsPrimaryKey { get { return ThisKey.All(m => m.IsPrimaryKey); } }\r
--            public override MetaDataMember ThisMember { get { return member; } }\r
--        }\r
--\r
--        abstract class XmlMetaDataMember : MetaDataMember\r
--        {\r
--            internal XmlMetaModel model;\r
--            internal XmlMetaType type;\r
--            internal MemberInfo member, storage;\r
--            MetaAccessor member_accessor, storage_accessor;\r
--            int ordinal;\r
--\r
--            protected XmlMetaDataMember(XmlMetaModel model, XmlMetaType type, string memberName, string storageName, int ordinal)\r
--            {\r
--                this.model = model;\r
--                this.type = type;\r
--                BindingFlags bf = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance;\r
--                if (type.Type.GetMember(memberName, bf).Length == 0)\r
--                    throw new ArgumentException(String.Format("Specified member '{0}' was not found in type '{1}'", memberName, type.Name));\r
--                if (type.Type.GetMember(storageName, bf).Length == 0)\r
--                    throw new ArgumentException(String.Format("Specified member '{0}' was not found in type '{1}'", storageName, type.Name));\r
--                this.member = type.Type.GetMember(memberName, bf)[0];\r
--                this.storage = type.Type.GetMember(storageName, bf)[0];\r
--                this.ordinal = ordinal;\r
--            }\r
--\r
--            public override bool CanBeNull { get { return member.GetMemberType().IsNullable(); } }\r
--            public override MetaType DeclaringType { get { return type; } }\r
--            public override bool IsDeferred { get { return false; } }\r
--            public override bool IsPersistent { get { return true; } }\r
--            public override MemberInfo Member { get { return member; } }\r
--            public override MetaAccessor MemberAccessor\r
--            {\r
--                get\r
--                {\r
--                    if (member_accessor == null)\r
--                        member_accessor = new XmlMetaAccessor(this, Member);\r
--                    return member_accessor;\r
--                }\r
--            }\r
--            public override int Ordinal { get { return ordinal; } }\r
--            public override MetaAccessor StorageAccessor\r
--            {\r
--                get\r
--                {\r
--                    if (storage_accessor == null)\r
--                        storage_accessor = new XmlMetaAccessor(this, StorageMember);\r
--                    return storage_accessor;\r
--                }\r
--            }\r
--            public override MemberInfo StorageMember { get { return storage; } }\r
--            public override Type Type { get { return member.GetMemberType(); } }\r
--\r
--            public override bool IsDeclaredBy(MetaType type)\r
--            {\r
--                return this.type == type;\r
--            }\r
--        }\r
--\r
--        class XmlColumnMetaDataMember : XmlMetaDataMember\r
--        {\r
--            DbmlColumn c;\r
--\r
--            public XmlColumnMetaDataMember(XmlMetaModel model, XmlMetaType type, DbmlColumn column, int ordinal)\r
--                : base(model, type, column.Member, column.Storage, ordinal)\r
--            {\r
--                this.c = column;\r
--            }\r
--\r
--            public override MetaAssociation Association { get { return null; } }\r
--            public override AutoSync AutoSync { get { return (AutoSync)c.AutoSync; } }\r
--            public override string DbType { get { return c.DbType; } }\r
--            [DbLinqToDo]\r
--            public override MetaAccessor DeferredSourceAccessor\r
--            {\r
--                get { throw new NotImplementedException(); }\r
--            }\r
--            [DbLinqToDo]\r
--            public override MetaAccessor DeferredValueAccessor\r
--            {\r
--                get { throw new NotImplementedException(); }\r
--            }\r
--\r
--            public override string Expression { get { return c.Expression; } }\r
--            public override bool IsAssociation { get { return false; } }\r
--            public override bool IsDbGenerated { get { return c.IsDbGenerated; } }\r
--            public override bool IsDiscriminator { get { return c.IsDiscriminator; } }\r
--            public override bool IsPrimaryKey { get { return c.IsPrimaryKey; } }\r
--            public override bool IsVersion { get { return c.IsVersion; } }\r
--            [DbLinqToDo]\r
--            public override MethodInfo LoadMethod\r
--            {\r
--                get\r
--                {\r
--                    throw new NotImplementedException();\r
--                }\r
--            }\r
--            public override string MappedName { get { return c.Name; } }\r
--            public override string Name { get { return c.Name ?? c.Member; } }\r
--            public override UpdateCheck UpdateCheck { get { return c.UpdateCheck; } }\r
--        }\r
--\r
--        class XmlAssociationMetaDataMember : XmlMetaDataMember\r
--        {\r
--            DbmlAssociation a;\r
--            XmlMetaAssociation ma;\r
--\r
--            public XmlAssociationMetaDataMember(XmlMetaModel model, XmlMetaType type, DbmlAssociation association, int ordinal)\r
--                : base(model, type, association.Member, association.Storage, ordinal)\r
--            {\r
--                this.a = association;\r
--            }\r
--\r
--            public override MetaAssociation Association\r
--            {\r
--                get\r
--                {\r
--                    if (ma == null)\r
--                        this.ma = new XmlMetaAssociation(type, this, a);\r
--                    return ma;\r
--                }\r
--            }\r
--            public override AutoSync AutoSync { get { return AutoSync.Never; } }\r
--            public override string DbType { get { return String.Empty; } }\r
--            [DbLinqToDo]\r
--            public override MetaAccessor DeferredSourceAccessor\r
--            {\r
--                get { throw new NotImplementedException(); }\r
--            }\r
--            [DbLinqToDo]\r
--            public override MetaAccessor DeferredValueAccessor\r
--            {\r
--                get { throw new NotImplementedException(); }\r
--            }\r
--\r
--            public override string Expression { get { return String.Empty; } }\r
--            public override bool IsAssociation { get { return true; } }\r
--            public override bool IsDbGenerated { get { return false; } }\r
--            public override bool IsDiscriminator { get { return false; } }\r
--            [DbLinqToDo]\r
--            public override bool IsPrimaryKey\r
--            {\r
--                get { throw new NotImplementedException(); }\r
--            }\r
--            [DbLinqToDo]\r
--            public override bool IsVersion\r
--            {\r
--                get { throw new NotImplementedException(); }\r
--            }\r
--            [DbLinqToDo]\r
--            public override MethodInfo LoadMethod\r
--            {\r
--                get\r
--                {\r
--                    throw new NotImplementedException();\r
--                }\r
--            }\r
--            public override string MappedName { get { return a.Member; } }\r
--            public override string Name { get { return a.Name; } }\r
--            public override UpdateCheck UpdateCheck\r
--            {\r
--                get\r
--                {\r
--                    throw new NotImplementedException();\r
--                }\r
--            }\r
--        }\r
--\r
--        class XmlMetaAccessor : MetaAccessor\r
--        {\r
--            XmlMetaDataMember member;\r
--            MemberInfo member_info;\r
--\r
--            public XmlMetaAccessor(XmlMetaDataMember member, MemberInfo memberInfo)\r
--            {\r
--                this.member = member;\r
--                this.member_info = memberInfo;\r
--            }\r
--\r
--            public override Type Type\r
--            {\r
--                get { return member_info is FieldInfo ? ((FieldInfo)member_info).FieldType : ((PropertyInfo)member_info).PropertyType; }\r
--            }\r
--\r
--            [DbLinqToDo]\r
--            public override object GetBoxedValue(object instance)\r
--            {\r
--                throw new NotImplementedException();\r
--            }\r
--\r
--            [DbLinqToDo]\r
--            public override void SetBoxedValue(ref object instance, object value)\r
--            {\r
--                throw new NotImplementedException();\r
--            }\r
--        }\r
--\r
--        class XmlMetaFunction : MetaFunction\r
--        {\r
--            XmlMetaModel model;\r
--            DbmlFunction f;\r
--            MethodInfo method;\r
--            ReadOnlyCollection<MetaParameter> parameters;\r
--            ReadOnlyCollection<MetaType> result_types;\r
--            MetaParameter return_param;\r
--\r
--            public XmlMetaFunction(XmlMetaModel model, DbmlFunction function)\r
--            {\r
--                this.model = model;\r
--                this.f = function;\r
--                method = model.ContextType.GetMethod(function.Method);\r
--                return_param = new XmlMetaParameter(function.Return.DbType, String.Empty, method.ReturnParameter);\r
--            }\r
--\r
--            public override bool HasMultipleResults { get { return f.ElementTypes.Count > 0; } }\r
--            public override bool IsComposable { get { return f.IsComposable; } }\r
--            public override string MappedName { get { return f.Name; } }\r
--            public override MethodInfo Method { get { return method; } }\r
--            public override MetaModel Model { get { return model; } }\r
--            public override string Name { get { return f.Name; } }\r
--            public override ReadOnlyCollection<MetaParameter> Parameters\r
--            {\r
--                get\r
--                {\r
--                    if (parameters == null)\r
--                    {\r
--                        var l = new List<MetaParameter>();\r
--                        int i = 0;\r
--                        ParameterInfo[] mparams = method.GetParameters();\r
--                        foreach (var p in f.Parameters)\r
--                            l.Add(new XmlMetaParameter(p, mparams[i++]));\r
--                        parameters = new ReadOnlyCollection<MetaParameter>(l);\r
--                    }\r
--                    return parameters;\r
--                }\r
--            }\r
--            public override ReadOnlyCollection<MetaType> ResultRowTypes\r
--            {\r
--                get\r
--                {\r
--                    if (result_types == null)\r
--                    {\r
--                        var l = new List<MetaType>();\r
--                        foreach (var p in f.ElementTypes)\r
--                            l.Add(model.GetMetaType(model.GetTypeFromName(p.Name)));\r
--                        result_types = new ReadOnlyCollection<MetaType>(l.ToArray());\r
--                    }\r
--                    return result_types;\r
--                }\r
--            }\r
--            public override MetaParameter ReturnParameter { get { return return_param; } }\r
--        }\r
--    }\r
--}\r
index dbc8e1e91ac599af39da4af3c94a0629048de68a,dbc8e1e91ac599af39da4af3c94a0629048de68a..d5cbb2b8cb55ae8aba15e538023e140f4c30d4ac
@@@ -107,6 -107,6 +107,12 @@@ namespace DbLinqTest 
              new DataContext("DbLinqConnectionType=");\r
          }\r
  \r
++        [Test, ExpectedException(typeof(ArgumentException))]\r
++        public void Ctor_ConnectionString_DbLinqConnectionType_Empty2()\r
++        {\r
++            new DataContext("DbLinqConnectionType=;");\r
++        }\r
++\r
          [Test, ExpectedException(typeof(ArgumentException))]\r
          public void Ctor_ConnectionString_DbLinqConnectionType_Invalid()\r
          {\r
              new DataContext("DbLinqProvider=DbLinq.Sqlite.dll");\r
          }\r
  \r
++        [Test, ExpectedException(typeof(ArgumentNullException))]\r
++        public void Ctor_FileOrServerOrConnectionIsNull()\r
++        {\r
++            MappingSource mapping = new AttributeMappingSource();\r
++            string fileOrServerOrConnection = null;\r
++            new DataContext(fileOrServerOrConnection, mapping);\r
++        }\r
++\r
++        [Test, ExpectedException(typeof(ArgumentNullException))]\r
++        public void Ctor_MappingIsNull()\r
++        {\r
++            MappingSource mapping = null;\r
++            string fileOrServerOrConnection = null;\r
++            new DataContext("", mapping);\r
++        }\r
++\r
++#if !MONO_STRICT\r
++        [Test, ExpectedException(typeof(NotImplementedException))]\r
++        public void Ctor_FileOrServerOrConnectionIsFilename()\r
++        {\r
++            MappingSource mapping = new AttributeMappingSource();\r
++            string fileOrServerOrConnection = typeof(DataContextTest).Assembly.Location;\r
++            new DataContext(fileOrServerOrConnection, mapping);\r
++        }\r
++\r
++        [Test, ExpectedException(typeof(NotImplementedException))]\r
++        public void Ctor_FileOrServerOrConnectionIsServer()\r
++        {\r
++            MappingSource mapping = new AttributeMappingSource();\r
++            string fileOrServerOrConnection = "ThisIsAssumedToBeAServerName";\r
++            new DataContext(fileOrServerOrConnection, mapping);\r
++        }\r
++#endif\r
++\r
          [Test]\r
          public void Connection()\r
          {\r
index 11b0e0f1430761fe31ccf84b84d5ae420b149718,11b0e0f1430761fe31ccf84b84d5ae420b149718..682602e7cfb4f36e6aacf526b2f81050a040fe8c
@@@ -50,17 -50,17 +50,8 @@@ using nwind
              var employee = new Employee();\r
  \r
              db1.Employees.Attach(employee);\r
++            employee.Address = "new address";\r
  \r
--            // You can't attach the same object to multiple databases.\r
--            db2.Employees.Attach(employee);\r
--        }\r
--\r
--        [Test, ExpectedException(typeof(NotSupportedException))]\r
--        public void Attach03()\r
--        {\r
--            var db1 = CreateDB();\r
--            var db2 = CreateDB();\r
--            var employee = db1.Employees.First();\r
              db2.Employees.Attach(employee);\r
          }\r
  \r
index 4197f7e773e76f8147bf763c82d480a8d08b30c4,4197f7e773e76f8147bf763c82d480a8d08b30c4..64317c45b35e119c0700b93b85302cf61267ac39
@@@ -340,9 -340,9 +340,8 @@@ using DataLinq = DbLinq.Data.Linq
              Northwind db = CreateDB();\r
              var q = from t in db.Territories\r
                      select t;\r
--            var employeeCount = q.Count();\r
++            var territoryCount = q.FirstOrDefault();\r
              db.ObjectTrackingEnabled = false;\r
--            Assert.AreEqual(4, employeeCount, "Expected for employees, got count=" + employeeCount);\r
          }\r
  \r
          [Test]\r
              Northwind db = CreateDB();\r
              var q = from t in db.Territories\r
                      select t;\r
--            var employeeCount = q.Count();\r
++            var territoryCount = q.FirstOrDefault();\r
              db.DeferredLoadingEnabled = false;\r
--            Assert.AreEqual(4, employeeCount, "Expected for employees, got count=" + employeeCount);\r
          }\r
  \r
          [Test]\r
              db.ObjectTrackingEnabled = false;\r
              var q = from t in db.Territories\r
                      select t;\r
--            var employeeCount = q.Count();\r
++            var territoryCount = q.Count();\r
              db.SubmitChanges();\r
          }\r
  \r
++        [Test]\r
++        public void C16_GettingProperty_DeferredLoadingEnabled2False()\r
++        {\r
++            Northwind db = CreateDB();\r
++            db.DeferredLoadingEnabled = false;\r
++            var q = from t in db.Territories\r
++                    select t;\r
++            Territory territory = q.FirstOrDefault();\r
++            Assert.IsNotNull(territory);\r
++            Assert.IsNull(territory.Region);\r
++        }\r
++\r
++        [Test]\r
++        public void C17_GettingProperty_ObjectTrackingEnabled2False()\r
++        {\r
++            Northwind db = CreateDB();\r
++            db.ObjectTrackingEnabled = false;\r
++            var q = from t in db.Territories\r
++                    select t;\r
++            Territory territory = q.FirstOrDefault();\r
++            Assert.IsNotNull(territory);\r
++            Assert.IsNull(territory.Region);\r
++        }\r
++\r
++        [Test]\r
++        public void C18_GettingProperty_LazyLoaded()\r
++        {\r
++            Northwind db = CreateDB();\r
++            var q = from t in db.Territories\r
++                    select t;\r
++            Territory territory = q.FirstOrDefault();\r
++            Assert.IsNotNull(territory);\r
++            Assert.IsNotNull(territory.Region);\r
++        }\r
++\r
++\r
          #endregion\r
  \r
          #region region D - select first or last - calls IQueryable.Execute instead of GetEnumerator\r
index 883644668bcfae9ec6e14f6097763e14280ff303,883644668bcfae9ec6e14f6097763e14280ff303..65a46a8351f1a67ebecefb9556ddc56b3744db8c
@@@ -217,31 -217,31 +217,43 @@@ using nwind
          public void ListChangedEvent()\r
          {\r
              var db = CreateDB();\r
--            var customer = db.Customers.First();\r
++            var customer = db.Customers.Where(c => c.Orders.Count > 0).First();\r
++            Assert.Greater(customer.Orders.Count, 0);\r
              bool ok;\r
--            customer.Orders.ListChanged += delegate { ok = true; };\r
++            System.ComponentModel.ListChangedEventArgs args = null;\r
++            customer.Orders.ListChanged += delegate(object sender, System.ComponentModel.ListChangedEventArgs a) \r
++                { \r
++                    ok = true; \r
++                    args = a; \r
++                };\r
  \r
              ok = false;\r
++            args = null;\r
              customer.Orders.Remove(customer.Orders.First());\r
              Assert.IsTrue(ok);\r
  \r
              ok = false;\r
++            args = null;\r
              customer.Orders.Assign(Enumerable.Empty<Order>());\r
              Assert.IsTrue(ok);\r
  \r
              ok = false;\r
--            customer.Orders.Add(db.Orders.First(o => !customer.Orders.Contains(o)));\r
++            args = null;\r
++            customer.Orders.Add(db.Orders.First());\r
              Assert.IsTrue(ok);\r
  \r
              ok = false;\r
++            args = null;\r
              customer.Orders.Clear();\r
              Assert.IsTrue(ok);\r
  \r
              ok = false;\r
++            args = null;\r
              customer.Orders.Insert(0, new Order());\r
              Assert.IsTrue(ok);\r
  \r
              ok = false;\r
++            args = null;\r
              customer.Orders.RemoveAt(0);\r
              Assert.IsTrue(ok);\r
          }\r
index 83acecd4b59b6d59bb76558bdf754c9e3a9c8671,83acecd4b59b6d59bb76558bdf754c9e3a9c8671..3dc1ce7b66bc92710cad9e12a49e1e1f7380b4d9
@@@ -166,21 -166,21 +166,25 @@@ namespace DbLinq.Vendor.Implementatio
          /// </summary>\r
          public IDbConnection CreateDbConnection(string connectionString)\r
          {\r
--            var reConnectionType = new System.Text.RegularExpressions.Regex(@"DbLinqConnectionType=([^;]+)");\r
++            var reConnectionType = new System.Text.RegularExpressions.Regex(@"DbLinqConnectionType=([^;]*)");\r
++            string connTypeVal = null;\r
              if (!reConnectionType.IsMatch(connectionString))\r
--                throw new ArgumentException("No DbLinqConnectionType parameter found.  " +\r
--                    "Please specify the assembly qualified type name to use for the Connection Type.",\r
--                    "connectionString");\r
++            {\r
++                connTypeVal = "System.Data.SqlClient.SqlConnection, System.Data";\r
++            }\r
++            else\r
++            {\r
++                var    match        = reConnectionType.Match(connectionString);\r
++                connTypeVal         = match.Groups[1].Value;\r
++                connectionString    = reConnectionType.Replace(connectionString, "");\r
++            }\r
  \r
--            var    match        = reConnectionType.Match(connectionString);\r
--            string connTypeVal  = match.Groups[1].Value;\r
              var    connType     = Type.GetType(connTypeVal);\r
              if (connType == null)\r
                  throw new ArgumentException(string.Format(\r
                          "Could not load the specified DbLinqConnectionType `{0}'.",\r
                          connTypeVal),\r
                      "connectionString");\r
--            connectionString = reConnectionType.Replace(connectionString, "");\r
              return (IDbConnection)Activator.CreateInstance(connType, connectionString);\r
          }\r
      }\r