+++ /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