++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.
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
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
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
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
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
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
/// <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
/// </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
--- /dev/null
--- /dev/null
++#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
\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
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
<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
<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
<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
+++ /dev/null
--#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
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
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
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
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
/// </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