1
// Copyright (c) AlphaSierraPapa for the SharpDevelop Team (for details please see \doc\copyright.txt)
2
// This code is distributed under the GNU LGPL (for details please see \doc\license.txt)
7
using System.Collections.Generic;
10
using ICSharpCode.Data.EDMDesigner.Core.EDMObjects.SSDL;
11
using System.Xml.Linq;
12
using ICSharpCode.Data.EDMDesigner.Core.EDMObjects.SSDL.EntityType;
13
using ICSharpCode.Data.EDMDesigner.Core.EDMObjects.SSDL.Association;
14
using ICSharpCode.Data.EDMDesigner.Core.EDMObjects.SSDL.Property;
15
using ICSharpCode.Data.EDMDesigner.Core.EDMObjects.Common;
16
using ICSharpCode.Data.EDMDesigner.Core.EDMObjects.SSDL.Function;
17
using ICSharpCode.Data.EDMDesigner.Core.EDMObjects.CSDL.Common;
21
namespace ICSharpCode.Data.EDMDesigner.Core.IO
23
public class SSDLIO : IO
25
public static XDocument WriteXDocument(SSDLContainer ssdlContainer)
27
return new XDocument(new XDeclaration("1.0", "utf-8", null), WriteXElement(ssdlContainer));
30
public static XElement WriteXElement(SSDLContainer ssdlContainer)
33
XElement schema = new XElement(ssdlNamespace + "Schema",
34
new XAttribute("Namespace", ssdlContainer.Namespace),
35
new XAttribute("Alias", "Self"),
36
new XAttribute(XNamespace.Xmlns + "store", storeNamespace.NamespaceName),
37
new XAttribute("xmlns", ssdlNamespace.NamespaceName))
38
.AddAttribute("Provider", ssdlContainer.Provider)
39
.AddAttribute("ProviderManifestToken", ssdlContainer.ProviderManifestToken);
42
string entityContainerNamespace = string.Concat(ssdlContainer.Namespace, ".");
43
XElement entityContainer = new XElement(ssdlNamespace + "EntityContainer", new XAttribute("Name", ssdlContainer.Name));
44
schema.Add(entityContainer);
46
// EntityContainer : EntitySets
47
foreach (EntityType entityType in ssdlContainer.EntityTypes)
49
XElement entitySet = new XElement(ssdlNamespace + "EntitySet",
50
new XAttribute("Name", entityType.EntitySetName), new XAttribute("EntityType", string.Concat(entityContainerNamespace, entityType.Name)))
51
.AddAttribute(entityType.StoreType == StoreType.Views ? null : new XAttribute("Schema", entityType.Schema))
52
.AddAttribute("Table", entityType.Table)
53
.AddAttribute(storeNamespace, "Name", entityType.StoreName)
54
.AddAttribute(storeNamespace, "Schema", entityType.StoreSchema)
55
.AddAttribute(storeNamespace, "Type", entityType.StoreType)
56
.AddElement(string.IsNullOrEmpty(entityType.DefiningQuery) ? null : new XElement(ssdlNamespace + "DefiningQuery", entityType.DefiningQuery));
58
entityContainer.Add(entitySet);
61
// EntityContainer : Associations
62
foreach (Association association in ssdlContainer.AssociationSets)
64
XElement associationSet = new XElement(ssdlNamespace + "AssociationSet",
65
new XAttribute("Name", association.AssociationSetName), new XAttribute("Association", string.Concat(entityContainerNamespace, association.Name)));
67
string role2Name = association.Role2.Name;
69
// If the association end properties are the same properties
70
if (association.Role1.Name == association.Role2.Name && association.Role1.Type.Name == association.Role2.Type.Name)
74
new XElement(ssdlNamespace + "End", new XAttribute("Role", association.Role1.Name), new XAttribute("EntitySet", association.Role1.Type.Name)),
75
new XElement(ssdlNamespace + "End", new XAttribute("Role", role2Name), new XAttribute("EntitySet", association.Role2.Type.Name)));
77
entityContainer.Add(associationSet);
81
foreach (EntityType entityType in ssdlContainer.EntityTypes)
83
XElement entityTypeElement = new XElement(ssdlNamespace + "EntityType", new XAttribute("Name", entityType.Name));
85
XElement keys = new XElement(ssdlNamespace + "Key");
87
foreach (Property property in entityType.Properties)
89
// If we have a table then we set a key element if the current property is a primary key or part of a composite key.
90
// AND: If we have a view then we make a composite key of all non-nullable properties of the entity (VS2010 is also doing this).
91
if ((entityType.StoreType == StoreType.Tables && property.IsKey) || (entityType.StoreType == StoreType.Views && property.Nullable == false))
92
keys.Add(new XElement(ssdlNamespace + "PropertyRef", new XAttribute("Name", property.Name)));
96
entityTypeElement.Add(keys);
98
foreach (Property property in entityType.Properties)
100
entityTypeElement.Add(new XElement(ssdlNamespace + "Property", new XAttribute("Name", property.Name), new XAttribute("Type", property.Type))
101
.AddAttribute("Collation", property.Collation)
102
.AddAttribute("DefaultValue", property.DefaultValue)
103
.AddAttribute("FixedLength", property.FixedLength)
104
.AddAttribute("MaxLength", property.MaxLength)
105
.AddAttribute("Nullable", property.Nullable)
106
.AddAttribute("Precision", property.Precision)
107
.AddAttribute("Scale", property.Scale)
108
.AddAttribute("StoreGeneratedPattern", property.StoreGeneratedPattern)
109
.AddAttribute(storeNamespace, "Name", property.StoreName)
110
.AddAttribute(storeNamespace, "Schema", property.StoreSchema)
111
.AddAttribute(storeNamespace, "Type", property.StoreType)
112
.AddAttribute("Unicode", property.Unicode));
115
schema.AddElement(entityTypeElement);
118
foreach (Association association in ssdlContainer.AssociationSets)
120
string role2Name = association.Role2.Name;
122
// If the association end properties are the same properties
123
if (association.Role1.Name == association.Role2.Name && association.Role1.Type.Name == association.Role2.Type.Name)
126
XElement associationElement = new XElement(ssdlNamespace + "Association", new XAttribute("Name", association.Name),
127
new XElement(ssdlNamespace + "End", new XAttribute("Role", association.Role1.Name), new XAttribute("Type", string.Concat(entityContainerNamespace, association.Role1.Type.Name)), new XAttribute("Multiplicity", CardinalityStringConverter.CardinalityToString(association.Role1.Cardinality))),
128
new XElement(ssdlNamespace + "End", new XAttribute("Role", role2Name), new XAttribute("Type", string.Concat(entityContainerNamespace, association.Role2.Type.Name)), new XAttribute("Multiplicity", CardinalityStringConverter.CardinalityToString(association.Role2.Cardinality))));
130
string dependentRoleName = association.DependantRole.Name;
132
// If the association end properties are the same properties
133
if (association.PrincipalRole.Name == association.DependantRole.Name && association.PrincipalRole.Type.Name == association.DependantRole.Type.Name)
134
dependentRoleName += "1";
136
XElement principalRoleElement = new XElement(ssdlNamespace + "Principal", new XAttribute("Role", association.PrincipalRole.Name));
137
foreach (Property property in association.PrincipalRole.Properties)
138
principalRoleElement.Add(new XElement(ssdlNamespace + "PropertyRef", new XAttribute("Name", property.Name)));
140
XElement dependentRoleElement = new XElement(ssdlNamespace + "Dependent", new XAttribute("Role", dependentRoleName));
141
foreach (Property property in association.DependantRole.Properties)
142
dependentRoleElement.Add(new XElement(ssdlNamespace + "PropertyRef", new XAttribute("Name", property.Name)));
144
XElement referentialConstraintElement = new XElement(ssdlNamespace + "ReferentialConstraint", principalRoleElement, dependentRoleElement);
145
associationElement.Add(referentialConstraintElement);
147
schema.Add(associationElement);
150
foreach (Function function in ssdlContainer.Functions)
152
XElement functionElement = new XElement(ssdlNamespace + "Function", new XAttribute("Name", function.Name))
153
.AddAttribute("Aggregate", function.Aggregate)
154
.AddAttribute("BuiltIn", function.BuiltIn)
155
.AddAttribute("CommandText", function.CommandText)
156
.AddAttribute("IsComposable", function.IsComposable)
157
.AddAttribute("NiladicFunction", function.NiladicFunction)
158
.AddAttribute("ReturnType", function.ReturnType)
159
.AddAttribute("StoreFunctionName", function.StoreFunctionName)
160
.AddAttribute("ParameterTypeSemantics", function.ParameterTypeSemantics)
161
.AddAttribute("Schema", function.Schema)
162
.AddAttribute(storeNamespace, "Name", function.StoreName)
163
.AddAttribute(storeNamespace, "Schema", function.StoreSchema)
164
.AddAttribute(storeNamespace, "Type", function.StoreType);
166
foreach (FunctionParameter functionParameter in function.Parameters)
168
functionElement.Add(new XElement(ssdlNamespace + "Parameter",
169
new XAttribute("Name", functionParameter.Name), new XAttribute("Type", functionParameter.Type), new XAttribute("Mode", functionParameter.Mode))
170
.AddAttribute("MaxLength", functionParameter.MaxLength)
171
.AddAttribute("Precision", functionParameter.Precision)
172
.AddAttribute("Scale", functionParameter.Scale)
173
.AddAttribute(storeNamespace, "Name", functionParameter.StoreName)
174
.AddAttribute(storeNamespace, "Schema", functionParameter.StoreSchema)
175
.AddAttribute(storeNamespace, "Type", functionParameter.StoreType));
178
schema.Add(functionElement);
184
public static SSDLContainer ReadXElement(XElement ssdlXElement)
186
XElement schemaElement = ssdlXElement.Element(XName.Get("StorageModels", edmxNamespace.NamespaceName)).Element(XName.Get("Schema", ssdlNamespace.NamespaceName));
188
if (schemaElement == null || schemaElement.IsEmpty)
191
XElement entityContainerElement = schemaElement.Element(XName.Get("EntityContainer", ssdlNamespace.NamespaceName));
193
var value = new SSDLContainer { Namespace = schemaElement.Attribute("Namespace").Value, Name = entityContainerElement.Attribute("Name").Value };
194
SetStringValueFromAttribute(schemaElement, "Provider", provider => value.Provider = provider);
195
SetStringValueFromAttribute(schemaElement, "ProviderManifestToken", provider => value.ProviderManifestToken = provider);
199
foreach (var entitySetElement in entityContainerElement.Elements(XName.Get("EntitySet", ssdlNamespace.NamespaceName)))
201
var entityType = new EntityType { EntitySetName = entitySetElement.Attribute("Name").Value };
202
var entityTypeName = GetName(entitySetElement.Attribute("EntityType").Value);
203
entityType.Name = entityTypeName;
204
SetEnumValueFromAttribute<StoreType>(entitySetElement, "Type", storeNamespace.NamespaceName, storeType => entityType.StoreType = storeType);
205
SetStringValueFromAttribute(entitySetElement, "Schema", schema => entityType.Schema = schema);
206
SetStringValueFromAttribute(entitySetElement, "Name", storeNamespace.NamespaceName, storeName => entityType.StoreName = storeName);
207
SetStringValueFromAttribute(entitySetElement, "Schema", storeNamespace.NamespaceName, storeSchema => entityType.StoreSchema = storeSchema);
208
SetStringValueFromAttribute(entitySetElement, "Table", table => entityType.Table = table);
209
SetStringValueFromElement(entitySetElement, "DefiningQuery", ssdlNamespace.NamespaceName, query => entityType.DefiningQuery = query);
212
var entityTypeElement = schemaElement.Elements(XName.Get("EntityType", ssdlNamespace.NamespaceName)).First(etElement => etElement.Attribute("Name").Value == entityTypeName);
213
foreach (var propertyElement in entityTypeElement.Elements(XName.Get("Property", ssdlNamespace.NamespaceName)))
215
var name = propertyElement.Attribute("Name").Value;
216
var property = new Property(entityType) { Name = name, Type = propertyElement.Attribute("Type").Value, IsKey = entityTypeElement.Element(XName.Get("Key", ssdlNamespace.NamespaceName)).Elements(XName.Get("PropertyRef", ssdlNamespace.NamespaceName)).Where(pr => pr.Attribute("Name").Value == name).Any() };
217
SetBoolValueFromAttribute(propertyElement, "Nullable", nullable => property.Nullable = nullable);
218
SetIntValueFromAttribute(propertyElement, "MaxLength", maxLength => property.MaxLength = maxLength);
219
SetBoolValueFromAttribute(propertyElement, "FixedLength", fixedLength => property.FixedLength = fixedLength);
220
SetIntValueFromAttribute(propertyElement, "Precision", precision => property.Precision = precision);
221
SetIntValueFromAttribute(propertyElement, "Scale", scale => property.Scale = scale);
222
SetStringValueFromAttribute(propertyElement, "Collation", collation => property.Collation = collation);
223
SetStringValueFromAttribute(propertyElement, "DefaultValue", defaultValue => property.DefaultValue = defaultValue);
224
SetBoolValueFromAttribute(propertyElement, "Unicode", unicode => property.Unicode = unicode);
225
SetEnumValueFromAttribute<StoreGeneratedPattern>(propertyElement, "StoreGeneratedPattern", storeGeneratedPattern => property.StoreGeneratedPattern = storeGeneratedPattern);
226
SetStringValueFromAttribute(propertyElement, "Name", storeNamespace.NamespaceName, storeName => property.StoreName = storeName);
227
SetStringValueFromAttribute(propertyElement, "Schema", storeNamespace.NamespaceName, storeSchema => property.StoreSchema = storeSchema);
228
SetStringValueFromAttribute(propertyElement, "Type", storeNamespace.NamespaceName, storeType => property.StoreType = storeType);
229
entityType.Properties.Add(property);
231
#endregion Properties
233
value.EntityTypes.Add(entityType);
236
#endregion EntitySets
238
#region AssociationSets
240
foreach (var associationSetElement in entityContainerElement.Elements(XName.Get("AssociationSet", ssdlNamespace.NamespaceName)))
242
var association = new Association { AssociationSetName = associationSetElement.Attribute("Name").Value };
243
var associationName = GetName(associationSetElement.Attribute("Association").Value);
244
association.Name = associationName;
247
var associationElement = schemaElement.Elements(XName.Get("Association", ssdlNamespace.NamespaceName)).First(aElement => aElement.Attribute("Name").Value == associationName);
248
bool isPrincipal = true;
249
foreach (var roleElement in associationSetElement.Elements(XName.Get("End", ssdlNamespace.NamespaceName)))
251
var roleName = roleElement.Attribute("Role").Value;
252
var role = new Role { Name = roleName, Type = value.EntityTypes.GetByName(roleElement.Attribute("EntitySet").Value) };
253
SetCardinalityValueFromAttribute(associationElement.Elements(XName.Get("End", ssdlNamespace.NamespaceName)).First(are => are.Attribute("Role").Value == roleName), cardinality => role.Cardinality = cardinality);
254
var referentialConstraintElement = associationElement.Element(XName.Get("ReferentialConstraint", ssdlNamespace.NamespaceName));
255
if (referentialConstraintElement != null)
257
var principalElement = referentialConstraintElement.Element(XName.Get("Principal", ssdlNamespace.NamespaceName));
258
if (principalElement.Attribute("Role").Value == role.Name)
261
association.PrincipalRole = role;
263
EventedObservableCollection<Property> properties = new EventedObservableCollection<Property>();
265
foreach (XElement element in principalElement.Elements(XName.Get("PropertyRef", ssdlNamespace.NamespaceName)))
267
foreach (Property property in role.Type.Properties)
269
if (property.Name == element.Attribute("Name").Value)
270
properties.Add(property);
274
role.Properties = properties;
279
association.DependantRole = role;
281
EventedObservableCollection<Property> properties = new EventedObservableCollection<Property>();
282
XElement dependentElement = referentialConstraintElement.Element(XName.Get("Dependent", ssdlNamespace.NamespaceName));
284
foreach (XElement element in dependentElement.Elements(XName.Get("PropertyRef", ssdlNamespace.NamespaceName)))
286
foreach (Property property in role.Type.Properties)
288
if (property.Name == element.Attribute("Name").Value)
289
properties.Add(property);
293
role.Properties = properties;
298
association.Role1 = role;
302
association.Role2 = role;
307
value.AssociationSets.Add(association);
310
#endregion AssociationSets
314
foreach (var functionElement in schemaElement.Elements(XName.Get("Function", ssdlNamespace.NamespaceName)))
316
var function = new Function { Name = functionElement.Attribute("Name").Value };
317
SetBoolValueFromAttribute(functionElement, "Aggregate", aggregate => function.Aggregate = aggregate);
318
SetBoolValueFromAttribute(functionElement, "BuiltIn", builtIn => function.BuiltIn = builtIn);
319
SetBoolValueFromAttribute(functionElement, "IsComposable", isComposable => function.IsComposable = isComposable);
320
SetBoolValueFromAttribute(functionElement, "NiladicFunction", niladicFunction => function.NiladicFunction = niladicFunction);
321
SetStringValueFromAttribute(functionElement, "Schema", schema => function.Schema = schema);
322
SetStringValueFromAttribute(functionElement, "Name", storeNamespace.NamespaceName, name => function.StoreName = name);
323
SetStringValueFromAttribute(functionElement, "Schema", storeNamespace.NamespaceName, schema => function.StoreSchema = schema);
324
SetStringValueFromAttribute(functionElement, "Type", storeNamespace.NamespaceName, type => function.StoreType = type);
325
SetStringValueFromAttribute(functionElement, "FunctionName", storeNamespace.NamespaceName, functionName => function.StoreFunctionName = functionName);
326
SetEnumValueFromAttribute<ParameterTypeSemantics>(functionElement, "ParameterTypeSemantics", parameterTypeSemantics => function.ParameterTypeSemantics = parameterTypeSemantics);
330
foreach (var parameterElement in functionElement.Elements(XName.Get("Parameter", ssdlNamespace.NamespaceName)))
332
var parameter = new FunctionParameter { Name = parameterElement.Attribute("Name").Value, Type = parameterElement.Attribute("Type").Value };
333
SetEnumValueFromAttribute<ParameterMode>(parameterElement, "Mode", mode => parameter.Mode = mode);
334
SetIntValueFromAttribute(parameterElement, "MaxLength", maxLength => parameter.MaxLength = maxLength);
335
SetIntValueFromAttribute(parameterElement, "Precision", precision => parameter.Precision = precision);
336
SetIntValueFromAttribute(parameterElement, "Scale", scale => parameter.Scale = scale);
337
SetStringValueFromAttribute(parameterElement, "Name", storeNamespace.NamespaceName, name => parameter.StoreName = name);
338
SetStringValueFromAttribute(parameterElement, "Schema", storeNamespace.NamespaceName, schema => parameter.StoreSchema = schema);
339
SetStringValueFromAttribute(parameterElement, "Type", storeNamespace.NamespaceName, type => parameter.StoreType = type);
341
function.Parameters.Add(parameter);
344
#endregion Parameters
346
value.Functions.Add(function);