Code:
/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / fx / src / DataEntityDesign / Design / System / Data / Entity / Design / EntityViewGeneration / EntityViewGenerator.cs / 1599186 / EntityViewGenerator.cs
//----------------------------------------------------------------------
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// @owner [....]
// @backupOwner [....]
//---------------------------------------------------------------------
using System;
using System.CodeDom;
using System.CodeDom.Compiler;
using System.IO;
using System.Collections.Generic;
using System.Text;
using System.Data;
using System.Data.SqlClient;
using System.Data.Metadata.Edm;
using System.Data.Mapping;
using System.Data.EntityClient;
using System.Data.EntityModel;
using System.Data.Common.CommandTrees;
using System.Reflection;
using System.Security.Cryptography;
using System.Data.Entity.Design.Common;
using System.Diagnostics;
using System.Globalization;
using System.Data.Common.Utils;
using Microsoft.Build.Utilities;
using System.Runtime.Versioning;
using System.Linq;
namespace System.Data.Entity.Design
{
///
/// EntityViewGenerator class produces the views for the extents in the passed in StorageMappingItemCollection.
/// The views are written as code to the passed in output stream. There are a set of options that user
/// can use to control the code generation process. The options should be apssed into the constrcutor.
/// While storing the views in the code, the view generator class also stores a Hash value produced based
/// on the content of the views and the names of extents. We also generate a hash for each schema file( csdl, ssdl and msl)
/// that was used in view generation process and store the hash in the generated code.The entity runtime will try to discover this
/// type and if it does discover it will use the generated views in this type. The discovery process is
/// explained in detail in the comments for StorageMappingItemCollection class.
/// The runtime will throw an exception if any of the the hash values produced in the design time does not match
/// the hash values produced at the runtime.
///
public class EntityViewGenerator
{
#region Constructors
///
/// Create the instance of ViewGenerator with the given language option.
///
/// Language Option for generated code.
public EntityViewGenerator(LanguageOption languageOption)
{
m_languageOption = EDesignUtil.CheckLanguageOptionArgument(languageOption, "languageOption");
}
///
/// Create the instance of ViewGenerator using C# as the default
/// language option.
///
public EntityViewGenerator()
: this(LanguageOption.GenerateCSharpCode)
{
}
#endregion
#region Fields
private LanguageOption m_languageOption;
private static readonly int MAXONELINELENGTH = 2046;
private static readonly int ONELINELENGTH = 80;
#endregion
#region Properties
///
/// Language Option for generated code.
///
public LanguageOption LanguageOption
{
get { return m_languageOption; }
set { m_languageOption = EDesignUtil.CheckLanguageOptionArgument(value, "value"); }
}
#endregion
#region Methods
///
/// Generates the views for the extents in the mapping item collection and produces
/// the code for a type that will cache these views. The methods also produces
/// a hash based on the StorageEntityContainerMapping, which contains all the
/// metadata and mapping. It also produces a hash based
/// on the view content and the name of the extents.
///
/// Mapping Item Collection for which views should be generated
/// Uri to which generated code needs to be written
[ResourceExposure(ResourceScope.Machine)] //Exposes the outputPath as part of ConnectionString which are a Machine resource.
[ResourceConsumption(ResourceScope.Machine)] //For StreamWriter constructor call. But the path to the stream is not created in this method.
[CLSCompliant(false)]
public IList GenerateViews(StorageMappingItemCollection mappingCollection, string outputPath)
{
EDesignUtil.CheckArgumentNull(mappingCollection, "mappingCollection");
EDesignUtil.CheckStringArgument(outputPath, "outputPath");
TextWriter outputWriter = null;
try
{
return InternalGenerateViews(mappingCollection, () => new StreamWriter(outputPath), out outputWriter);
}
finally
{
if (outputWriter != null)
{
outputWriter.Dispose();
}
}
}
///
/// Generates the views for the extents in the mapping item collection and produces
/// the code for a type that will cache these views. The methods also produces
/// a hash based on the storageEntityContainerMapping object, which contains all the
/// metadata and mapping. It also produces a hash based
/// on the view content and the name of the extents.
///
/// Mapping Item Collection for which views should be generated
/// Output writer to which we want to write the code
[CLSCompliant(false)]
public IList GenerateViews(StorageMappingItemCollection mappingCollection, TextWriter outputWriter)
{
EDesignUtil.CheckArgumentNull(mappingCollection, "mappingCollection");
EDesignUtil.CheckArgumentNull(outputWriter, "outputWriter");
TextWriter writer;
return InternalGenerateViews(mappingCollection, () => outputWriter, out writer);
}
///
/// Generates the views for the extents in the mapping item collection and produces
/// the code for a type that will cache these views. The methods also produces
/// a hash based on the storageEntityContainerMapping object, which contains all the
/// metadata and mapping. It also produces a hash based
/// on the view content and the name of the extents.
///
/// Mapping Item Collection for which views should be generated
/// Output writer to which we want to write the code
[CLSCompliant(false)]
public IList GenerateViews(StorageMappingItemCollection mappingCollection, TextWriter outputWriter, Version targetEntityFrameworkVersion)
{
EDesignUtil.CheckArgumentNull(mappingCollection, "mappingCollection");
EDesignUtil.CheckTargetEntityFrameworkVersionArgument(targetEntityFrameworkVersion, "targetEntityFrameworkVersion");
CheckForCompatibleSchemaAndTarget(mappingCollection, targetEntityFrameworkVersion, "targetEntityFrameworkVersion");
return GenerateViews(mappingCollection, outputWriter);
}
private static void CheckForCompatibleSchemaAndTarget(StorageMappingItemCollection mappingCollection, Version targetEntityFrameworkVersion, string parameter)
{
if (targetEntityFrameworkVersion < EntityFrameworkVersions.ConvertToVersion(mappingCollection.MappingVersion) ||
targetEntityFrameworkVersion < EntityFrameworkVersions.ConvertToVersion(mappingCollection.EdmItemCollection.EdmVersion))
{
throw EDesignUtil.Argument(Strings.TargetVersionEdmOrMslSchemaVersionMismatch(parameter), null);
}
}
private IList InternalGenerateViews(
StorageMappingItemCollection mappingCollection,
Func GetWriter,
out TextWriter outputWriter)
{
IList schemaErrors;
CodeDomProvider provider;
Dictionary generatedViews;
if (GetViewsWithErrors(mappingCollection, out provider, out schemaErrors, out generatedViews))
{
outputWriter = null;
return schemaErrors;
}
outputWriter = GetWriter();
GenerateAndStoreViews(mappingCollection, generatedViews,
outputWriter, provider, schemaErrors);
return schemaErrors;
}
///
/// Validates the mappingCollections and returns the schemaErrors.
///
///
/// list of EdmSchemaError
[CLSCompliant(false)]
public static IList Validate(StorageMappingItemCollection mappingCollection, Version targetEntityFrameworkVersion)
{
EDesignUtil.CheckTargetEntityFrameworkVersionArgument(targetEntityFrameworkVersion, "targetEntityFrameworkVersion");
CheckForCompatibleSchemaAndTarget(mappingCollection, targetEntityFrameworkVersion, "targetEntityFrameworkVersion");
return Validate(mappingCollection);
}
///
/// Validates the mappingCollections and returns the schemaErrors.
///
///
/// list of EdmSchemaError
[CLSCompliant(false)]
public static IList Validate(StorageMappingItemCollection mappingCollection)
{
// purpose of this API is to validate the mappingCollection, it basically will call GetViews
EDesignUtil.CheckArgumentNull(mappingCollection, "mappingCollection");
// we need a temp var to to pass it to GetViews (since we will directly invoke GetViews)
Dictionary generatedViews;
// mappingCollection will be validated and schemaErrors will be returned from GetViews API
IList schemaErrors;
GetViews(mappingCollection, out schemaErrors, out generatedViews);
Debug.Assert(schemaErrors != null, "schemaErrors is null");
return schemaErrors;
}
private bool GetViewsWithErrors(StorageMappingItemCollection mappingCollection, out CodeDomProvider provider, out IList schemaErrors, out Dictionary generatedViews)
{
GetViewsAndCodeDomProvider(mappingCollection, out provider, out schemaErrors, out generatedViews);
//If the generated views are empty because of errors or warnings, then don't create an output file.
if (generatedViews.Count == 0 && schemaErrors.Count > 0)
{
return true;
}
return false;
}
private void GetViewsAndCodeDomProvider(StorageMappingItemCollection mappingCollection, out CodeDomProvider provider, out IList schemaErrors, out Dictionary generatedViews)
{
//Create a CodeDomProvider based on options.
provider = null;
switch (m_languageOption)
{
case LanguageOption.GenerateCSharpCode:
provider = new Microsoft.CSharp.CSharpCodeProvider();
break;
case LanguageOption.GenerateVBCode:
provider = new Microsoft.VisualBasic.VBCodeProvider();
break;
}
//Get the views for the Entity Sets and Association Sets in the mapping item collection
GetViews(mappingCollection, out schemaErrors, out generatedViews);
}
private static void GetViews(StorageMappingItemCollection mappingCollection,
out IList schemaErrors, out Dictionary generatedViews)
{
generatedViews = mappingCollection.GetViews(out schemaErrors);
}
///
/// Generates the code to store the views in a C# or a VB file based on the
/// options passed in by the user.
///
///
///
///
///
///
private static void GenerateAndStoreViews(StorageMappingItemCollection mappingCollection,
Dictionary generatedViews, TextWriter sourceWriter, CodeDomProvider provider, IList schemaErrors)
{
EdmItemCollection edmCollection = mappingCollection.EdmItemCollection;
StoreItemCollection storeCollection = mappingCollection.StoreItemCollection;
//Create an emtpty compile unit and build up the generated code
CodeCompileUnit compileUnit = new CodeCompileUnit();
//Add the namespace for generated code
CodeNamespace codeNamespace = new CodeNamespace(EntityViewGenerationConstants.NamespaceName);
//Add copyright notice to the namespace comment.
compileUnit.Namespaces.Add(codeNamespace);
foreach (var storageEntityContainerMapping in mappingCollection.GetItems())
{
//Throw warning when containerMapping contains query view for bug 547285.
if (HasQueryView(storageEntityContainerMapping))
{
schemaErrors.Add(new EdmSchemaError(
Strings.UnsupportedQueryViewInEntityContainerMapping(storageEntityContainerMapping.Identity),
(int)StorageMappingErrorCode.UnsupportedQueryViewInEntityContainerMapping,
EdmSchemaErrorSeverity.Warning));
continue;
}
#region Class Declaration
string edmContainerName = storageEntityContainerMapping.EdmEntityContainer.Name;
string storeContainerName = storageEntityContainerMapping.StorageEntityContainer.Name;
string hashOverMappingClosure = MetadataMappingHasherVisitor.GetMappingClosureHash(edmCollection.EdmVersion, storageEntityContainerMapping);
StringBuilder inputForTypeNameContent = new StringBuilder(hashOverMappingClosure);
string viewStorageTypeName = EntityViewGenerationConstants.ViewGenerationTypeNamePrefix + StringHashBuilder.ComputeHash(MetadataHelper.CreateMetadataHashAlgorithm(edmCollection.EdmVersion), inputForTypeNameContent.ToString()).ToUpperInvariant();
//Add typeof expression to get the type that contains ViewGen type. This will help us in avoiding to go through
//all the types in the assembly. I have also verified that this works with VB with a root namespace prepended to the
//namespace since VB is picking up the type correctly as long as it is in the same assembly even with out the root namespace.
CodeTypeOfExpression viewGenTypeOfExpression = new CodeTypeOfExpression(EntityViewGenerationConstants.NamespaceName + "." + viewStorageTypeName);
//Add the assembly attribute that marks the assembly as the one that contains the generated views
CodeAttributeDeclaration viewGenAttribute = new CodeAttributeDeclaration(EntityViewGenerationConstants.ViewGenerationCustomAttributeName);
CodeAttributeArgument viewGenTypeArgument = new CodeAttributeArgument(viewGenTypeOfExpression);
viewGenAttribute.Arguments.Add(viewGenTypeArgument);
compileUnit.AssemblyCustomAttributes.Add(viewGenAttribute);
//Add the type which will be the class that contains all the views in this assembly
CodeTypeDeclaration viewStoringType = CreateTypeForStoringViews(viewStorageTypeName);
//Add the constructor, this will be the only method that this type will contain
//Create empty constructor.
CodeConstructor viewStoringTypeConstructor = CreateConstructorForViewStoringType();
viewStoringType.Attributes = MemberAttributes.Public;
//Get an expression that expresses this instance
CodeThisReferenceExpression thisRef = new CodeThisReferenceExpression();
string viewHash = MetadataHelper.GenerateHashForAllExtentViewsContent(edmCollection.EdmVersion, GenerateDictionaryForEntitySetNameAndView(generatedViews));
CodeAssignStatement EdmEntityContainerNameStatement =
new CodeAssignStatement(
new CodeFieldReferenceExpression(thisRef, EntityViewGenerationConstants.EdmEntityContainerName),
new CodePrimitiveExpression(edmContainerName));
CodeAssignStatement StoreEntityContainerNameStatement =
new CodeAssignStatement(
new CodeFieldReferenceExpression(thisRef, EntityViewGenerationConstants.StoreEntityContainerName),
new CodePrimitiveExpression(storeContainerName));
CodeAssignStatement HashOverMappingClosureStatement =
new CodeAssignStatement(
new CodeFieldReferenceExpression(thisRef, EntityViewGenerationConstants.HashOverMappingClosure),
new CodePrimitiveExpression(hashOverMappingClosure));
CodeAssignStatement HashOverAllExtentViewsStatement =
new CodeAssignStatement(
new CodeFieldReferenceExpression(thisRef, EntityViewGenerationConstants.HashOverAllExtentViews),
new CodePrimitiveExpression(viewHash));
CodeAssignStatement ViewCountStatement =
new CodeAssignStatement(
new CodeFieldReferenceExpression(thisRef, EntityViewGenerationConstants.ViewCountPropertyName),
new CodePrimitiveExpression(generatedViews.Count));
viewStoringTypeConstructor.Statements.Add(EdmEntityContainerNameStatement);
viewStoringTypeConstructor.Statements.Add(StoreEntityContainerNameStatement);
viewStoringTypeConstructor.Statements.Add(HashOverMappingClosureStatement);
viewStoringTypeConstructor.Statements.Add(HashOverAllExtentViewsStatement);
viewStoringTypeConstructor.Statements.Add(ViewCountStatement);
//Add the constructor to the type
viewStoringType.Members.Add(viewStoringTypeConstructor);
//Add the method to store views to the type
CreateAndAddGetViewAtMethod(viewStoringType, generatedViews);
//Add the type to the namespace
codeNamespace.Types.Add(viewStoringType);
#endregion
}
if (codeNamespace.Types.Count > 0)
{
GenerateCode(sourceWriter, provider, compileUnit);
sourceWriter.Flush();
}
}
private static bool HasQueryView(StorageEntityContainerMapping storageEntityContainerMapping)
{
foreach (EntitySetBase extent in storageEntityContainerMapping.EdmEntityContainer.BaseEntitySets)
{
if (storageEntityContainerMapping.HasQueryViewForSetMap(extent.Name))
{
return true;
}
}
return false;
}
private static Dictionary GenerateDictionaryForEntitySetNameAndView(Dictionary dictionary)
{
Dictionary newDictionary = new Dictionary();
foreach (var item in dictionary)
{
newDictionary.Add(GetExtentFullName(item.Key), item.Value);
}
return newDictionary;
}
///
/// Write code to the given stream from the compile unit.
///
///
///
///
private static void GenerateCode(TextWriter sourceWriter, CodeDomProvider provider, CodeCompileUnit compileUnit)
{
CodeGeneratorOptions styleOptions = new CodeGeneratorOptions();
styleOptions.BracingStyle = "C";
styleOptions.BlankLinesBetweenMembers = true;
styleOptions.VerbatimOrder = true;
provider.GenerateCodeFromCompileUnit(compileUnit, sourceWriter, styleOptions);
}
///
/// Generate Code to put the views in the generated code.
///
///
///
///
private static void CreateAndAddGetViewAtMethod(CodeTypeDeclaration typeDeclaration, Dictionary generatedViews)
{
//Add the views to a method
CodeMemberMethod getViewAtMethod = new CodeMemberMethod();
getViewAtMethod.Name = EntityViewGenerationConstants.GetViewAtMethodName;
getViewAtMethod.ReturnType = new CodeTypeReference(typeof(KeyValuePair<,>).MakeGenericType(new Type[] { typeof(string), typeof(string) }));
CodeParameterDeclarationExpression parameter = new CodeParameterDeclarationExpression(new CodeTypeReference(typeof(int)), "index");
getViewAtMethod.Parameters.Add(parameter);
getViewAtMethod.Comments.Add(new CodeCommentStatement(EntityViewGenerationConstants.SummaryStartElement, true /*docComment*/));
getViewAtMethod.Comments.Add(new CodeCommentStatement(Strings.GetViewAtMethodComments, true /*docComment*/));
getViewAtMethod.Comments.Add(new CodeCommentStatement(EntityViewGenerationConstants.SummaryEndElement, true /*docComment*/));
getViewAtMethod.Attributes = MemberAttributes.Family | MemberAttributes.Override;
typeDeclaration.Members.Add(getViewAtMethod);
int index = 0;
CodeVariableReferenceExpression indexParameterReference = new CodeVariableReferenceExpression(getViewAtMethod.Parameters[0].Name);
foreach (KeyValuePair generatedViewPair in generatedViews)
{
// the CodeDom does not support the following scenarios
// 1. switch statement
// 2. if(){} else if(){}
// The original design here was to have the following code,
// if() { else { if(){} } }
// but this had some drawbacks as described in TFS workitem 590996
// Given the not supported scenarios in CodeDom, we choose only use if statement in this case
// if(index == 0)
CodeConditionStatement currentIf = new CodeConditionStatement(new CodeBinaryOperatorExpression(
indexParameterReference, CodeBinaryOperatorType.ValueEquality, new CodePrimitiveExpression(index)));
getViewAtMethod.Statements.Add(currentIf);
EntitySetBase entitySet = generatedViewPair.Key;
string extentFullName = GetExtentFullName(entitySet);
CodeMemberMethod viewMethod = CreateViewReturnMethod(extentFullName, index, generatedViewPair.Value);
typeDeclaration.Members.Add(viewMethod);
// return GetNorthwindContext_Customers();
CodeMethodReturnStatement returnViewMethodCall = new CodeMethodReturnStatement(new CodeMethodInvokeExpression(new CodeMethodReferenceExpression(null, viewMethod.Name)));
currentIf.TrueStatements.Add(returnViewMethodCall);
index++;
}
// if an invalid index is asked for throw
getViewAtMethod.Statements.Add(new CodeThrowExceptionStatement(
new CodeObjectCreateExpression(new CodeTypeReference(typeof(IndexOutOfRangeException)))));
}
private static CodeMemberMethod CreateViewReturnMethod(string extentFullName, int index, string viewText)
{
//Add the views to a method
CodeMemberMethod viewMethod = new CodeMemberMethod();
viewMethod.Name = "GetView" + index.ToString();
viewMethod.Attributes = MemberAttributes.Private;
viewMethod.ReturnType = new CodeTypeReference(typeof(KeyValuePair<,>).MakeGenericType(new Type[] { typeof(string), typeof(string) }));
viewMethod.Comments.Add(new CodeCommentStatement(EntityViewGenerationConstants.SummaryStartElement, true /*docComment*/));
viewMethod.Comments.Add(new CodeCommentStatement(Strings.IndividualViewComments(extentFullName), true /*docComment*/));
viewMethod.Comments.Add(new CodeCommentStatement(EntityViewGenerationConstants.SummaryEndElement, true /*docComment*/));
CodeExpression viewTextExpression;
// only use the StringBuilder if we have to.
if (viewText.Length > MAXONELINELENGTH)
{
CreateSizedStringBuilder(viewMethod.Statements, viewText.Length);
foreach (var appendExpression in GetAppendViewStringsExpressions(viewText))
{
// viewString.Append(xxx);
viewMethod.Statements.Add(appendExpression);
}
viewTextExpression = new CodeMethodInvokeExpression(GetViewStringBuilderVariable(), "ToString");
}
else
{
viewTextExpression = new CodePrimitiveExpression(viewText);
}
// return new System.Collections.Generic.KeyValuePair("dbo.Products", viewString.ToString());
// or
// return new System.Collections.Generic.KeyValuePair("dbo.Products", "SELECT value c...");
CodeObjectCreateExpression newExpression =
new CodeObjectCreateExpression(
viewMethod.ReturnType,
new CodePrimitiveExpression(extentFullName),
viewTextExpression);
viewMethod.Statements.Add(new CodeMethodReturnStatement(newExpression));
return viewMethod;
}
private static void CreateSizedStringBuilder(CodeStatementCollection statements, int capacity)
{
// StringBuilder viewString = new StringBuilder(237);
CodeVariableDeclarationStatement viewStringDeclaration = new CodeVariableDeclarationStatement(typeof(StringBuilder), "viewString");
CodeObjectCreateExpression viewStringConstruct = new CodeObjectCreateExpression(typeof(StringBuilder), new CodePrimitiveExpression(capacity));
viewStringDeclaration.InitExpression = viewStringConstruct;
statements.Add(viewStringDeclaration);
}
private static IEnumerable SplitViewStrings(string largeViewString)
{
for (int i = 0; i <= largeViewString.Length / ONELINELENGTH; i++)
{
if (i * ONELINELENGTH + ONELINELENGTH < largeViewString.Length)
{
yield return largeViewString.Substring(i * ONELINELENGTH, ONELINELENGTH);
}
else
{
// the very last part of the splited string
yield return largeViewString.Substring(i * ONELINELENGTH);
}
}
}
private static IEnumerable GetViewStringsAppendToStringBuilder(
params string[] viewStrings)
{
foreach (var viewString in viewStrings)
{
// viewString.Append("xxx");
yield return AppendStringToStringBuilder(GetViewStringBuilderVariable(), viewString);
}
}
private static CodeVariableReferenceExpression GetViewStringBuilderVariable()
{
return new CodeVariableReferenceExpression("viewString");
}
private static CodeMethodInvokeExpression AppendStringToStringBuilder(
CodeVariableReferenceExpression stringBuilder, string stringToAppend)
{
return new CodeMethodInvokeExpression(
stringBuilder, "Append", new CodePrimitiveExpression(stringToAppend));
}
private static IEnumerable GetAppendViewStringsExpressions(string viewString)
{
if (viewString.Length > MAXONELINELENGTH)
{
// if the string is longer than 2046 charactors, we splitted them in to 80 each
// and append them using StringBuilder
return GetViewStringsAppendToStringBuilder(SplitViewStrings(viewString).ToArray());
}
else
{
return GetViewStringsAppendToStringBuilder(viewString);
}
}
private static string GetExtentFullName(EntitySetBase entitySet)
{
//We store the full Extent Name in the generated code which is
//EntityContainer name + "." + entitysetName
return entitySet.EntityContainer.Name + EntityViewGenerationConstants.QualificationCharacter + entitySet.Name;
}
///
/// Get the constructor for the type that will contain the generated views
///
///
private static CodeConstructor CreateConstructorForViewStoringType()
{
CodeConstructor constructor = new CodeConstructor();
//Mark it as public
constructor.Attributes = MemberAttributes.Public;
//Add constructor comments
constructor.Comments.Add(new CodeCommentStatement(EntityViewGenerationConstants.SummaryStartElement, true /*docComment*/));
constructor.Comments.Add(new CodeCommentStatement(Strings.ConstructorComments, true /*docComment*/));
constructor.Comments.Add(new CodeCommentStatement(EntityViewGenerationConstants.SummaryEndElement, true /*docComment*/));
return constructor;
}
///
/// Get the type declaration for the type that will contain the views.
///
///
private static CodeTypeDeclaration CreateTypeForStoringViews(string viewStorageTypeName)
{
CodeTypeDeclaration typeDecl = new CodeTypeDeclaration(viewStorageTypeName);
typeDecl.TypeAttributes = TypeAttributes.Sealed | TypeAttributes.Public;
//This type should derive from the framework type EntityViewContainer which reduces the amount
//of generated code
typeDecl.BaseTypes.Add(EntityViewGenerationConstants.BaseTypeName);
//Add type comments
typeDecl.Comments.Add(new CodeCommentStatement(EntityViewGenerationConstants.SummaryStartElement, true /*docComment*/));
typeDecl.Comments.Add(new CodeCommentStatement(Strings.TypeComments, true /*docComment*/));
typeDecl.Comments.Add(new CodeCommentStatement(EntityViewGenerationConstants.SummaryEndElement, true /*docComment*/));
return typeDecl;
}
#endregion
}
}
// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
//----------------------------------------------------------------------
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// @owner [....]
// @backupOwner [....]
//---------------------------------------------------------------------
using System;
using System.CodeDom;
using System.CodeDom.Compiler;
using System.IO;
using System.Collections.Generic;
using System.Text;
using System.Data;
using System.Data.SqlClient;
using System.Data.Metadata.Edm;
using System.Data.Mapping;
using System.Data.EntityClient;
using System.Data.EntityModel;
using System.Data.Common.CommandTrees;
using System.Reflection;
using System.Security.Cryptography;
using System.Data.Entity.Design.Common;
using System.Diagnostics;
using System.Globalization;
using System.Data.Common.Utils;
using Microsoft.Build.Utilities;
using System.Runtime.Versioning;
using System.Linq;
namespace System.Data.Entity.Design
{
///
/// EntityViewGenerator class produces the views for the extents in the passed in StorageMappingItemCollection.
/// The views are written as code to the passed in output stream. There are a set of options that user
/// can use to control the code generation process. The options should be apssed into the constrcutor.
/// While storing the views in the code, the view generator class also stores a Hash value produced based
/// on the content of the views and the names of extents. We also generate a hash for each schema file( csdl, ssdl and msl)
/// that was used in view generation process and store the hash in the generated code.The entity runtime will try to discover this
/// type and if it does discover it will use the generated views in this type. The discovery process is
/// explained in detail in the comments for StorageMappingItemCollection class.
/// The runtime will throw an exception if any of the the hash values produced in the design time does not match
/// the hash values produced at the runtime.
///
public class EntityViewGenerator
{
#region Constructors
///
/// Create the instance of ViewGenerator with the given language option.
///
/// Language Option for generated code.
public EntityViewGenerator(LanguageOption languageOption)
{
m_languageOption = EDesignUtil.CheckLanguageOptionArgument(languageOption, "languageOption");
}
///
/// Create the instance of ViewGenerator using C# as the default
/// language option.
///
public EntityViewGenerator()
: this(LanguageOption.GenerateCSharpCode)
{
}
#endregion
#region Fields
private LanguageOption m_languageOption;
private static readonly int MAXONELINELENGTH = 2046;
private static readonly int ONELINELENGTH = 80;
#endregion
#region Properties
///
/// Language Option for generated code.
///
public LanguageOption LanguageOption
{
get { return m_languageOption; }
set { m_languageOption = EDesignUtil.CheckLanguageOptionArgument(value, "value"); }
}
#endregion
#region Methods
///
/// Generates the views for the extents in the mapping item collection and produces
/// the code for a type that will cache these views. The methods also produces
/// a hash based on the StorageEntityContainerMapping, which contains all the
/// metadata and mapping. It also produces a hash based
/// on the view content and the name of the extents.
///
/// Mapping Item Collection for which views should be generated
/// Uri to which generated code needs to be written
[ResourceExposure(ResourceScope.Machine)] //Exposes the outputPath as part of ConnectionString which are a Machine resource.
[ResourceConsumption(ResourceScope.Machine)] //For StreamWriter constructor call. But the path to the stream is not created in this method.
[CLSCompliant(false)]
public IList GenerateViews(StorageMappingItemCollection mappingCollection, string outputPath)
{
EDesignUtil.CheckArgumentNull(mappingCollection, "mappingCollection");
EDesignUtil.CheckStringArgument(outputPath, "outputPath");
TextWriter outputWriter = null;
try
{
return InternalGenerateViews(mappingCollection, () => new StreamWriter(outputPath), out outputWriter);
}
finally
{
if (outputWriter != null)
{
outputWriter.Dispose();
}
}
}
///
/// Generates the views for the extents in the mapping item collection and produces
/// the code for a type that will cache these views. The methods also produces
/// a hash based on the storageEntityContainerMapping object, which contains all the
/// metadata and mapping. It also produces a hash based
/// on the view content and the name of the extents.
///
/// Mapping Item Collection for which views should be generated
/// Output writer to which we want to write the code
[CLSCompliant(false)]
public IList GenerateViews(StorageMappingItemCollection mappingCollection, TextWriter outputWriter)
{
EDesignUtil.CheckArgumentNull(mappingCollection, "mappingCollection");
EDesignUtil.CheckArgumentNull(outputWriter, "outputWriter");
TextWriter writer;
return InternalGenerateViews(mappingCollection, () => outputWriter, out writer);
}
///
/// Generates the views for the extents in the mapping item collection and produces
/// the code for a type that will cache these views. The methods also produces
/// a hash based on the storageEntityContainerMapping object, which contains all the
/// metadata and mapping. It also produces a hash based
/// on the view content and the name of the extents.
///
/// Mapping Item Collection for which views should be generated
/// Output writer to which we want to write the code
[CLSCompliant(false)]
public IList GenerateViews(StorageMappingItemCollection mappingCollection, TextWriter outputWriter, Version targetEntityFrameworkVersion)
{
EDesignUtil.CheckArgumentNull(mappingCollection, "mappingCollection");
EDesignUtil.CheckTargetEntityFrameworkVersionArgument(targetEntityFrameworkVersion, "targetEntityFrameworkVersion");
CheckForCompatibleSchemaAndTarget(mappingCollection, targetEntityFrameworkVersion, "targetEntityFrameworkVersion");
return GenerateViews(mappingCollection, outputWriter);
}
private static void CheckForCompatibleSchemaAndTarget(StorageMappingItemCollection mappingCollection, Version targetEntityFrameworkVersion, string parameter)
{
if (targetEntityFrameworkVersion < EntityFrameworkVersions.ConvertToVersion(mappingCollection.MappingVersion) ||
targetEntityFrameworkVersion < EntityFrameworkVersions.ConvertToVersion(mappingCollection.EdmItemCollection.EdmVersion))
{
throw EDesignUtil.Argument(Strings.TargetVersionEdmOrMslSchemaVersionMismatch(parameter), null);
}
}
private IList InternalGenerateViews(
StorageMappingItemCollection mappingCollection,
Func GetWriter,
out TextWriter outputWriter)
{
IList schemaErrors;
CodeDomProvider provider;
Dictionary generatedViews;
if (GetViewsWithErrors(mappingCollection, out provider, out schemaErrors, out generatedViews))
{
outputWriter = null;
return schemaErrors;
}
outputWriter = GetWriter();
GenerateAndStoreViews(mappingCollection, generatedViews,
outputWriter, provider, schemaErrors);
return schemaErrors;
}
///
/// Validates the mappingCollections and returns the schemaErrors.
///
///
/// list of EdmSchemaError
[CLSCompliant(false)]
public static IList Validate(StorageMappingItemCollection mappingCollection, Version targetEntityFrameworkVersion)
{
EDesignUtil.CheckTargetEntityFrameworkVersionArgument(targetEntityFrameworkVersion, "targetEntityFrameworkVersion");
CheckForCompatibleSchemaAndTarget(mappingCollection, targetEntityFrameworkVersion, "targetEntityFrameworkVersion");
return Validate(mappingCollection);
}
///
/// Validates the mappingCollections and returns the schemaErrors.
///
///
/// list of EdmSchemaError
[CLSCompliant(false)]
public static IList Validate(StorageMappingItemCollection mappingCollection)
{
// purpose of this API is to validate the mappingCollection, it basically will call GetViews
EDesignUtil.CheckArgumentNull(mappingCollection, "mappingCollection");
// we need a temp var to to pass it to GetViews (since we will directly invoke GetViews)
Dictionary generatedViews;
// mappingCollection will be validated and schemaErrors will be returned from GetViews API
IList schemaErrors;
GetViews(mappingCollection, out schemaErrors, out generatedViews);
Debug.Assert(schemaErrors != null, "schemaErrors is null");
return schemaErrors;
}
private bool GetViewsWithErrors(StorageMappingItemCollection mappingCollection, out CodeDomProvider provider, out IList schemaErrors, out Dictionary generatedViews)
{
GetViewsAndCodeDomProvider(mappingCollection, out provider, out schemaErrors, out generatedViews);
//If the generated views are empty because of errors or warnings, then don't create an output file.
if (generatedViews.Count == 0 && schemaErrors.Count > 0)
{
return true;
}
return false;
}
private void GetViewsAndCodeDomProvider(StorageMappingItemCollection mappingCollection, out CodeDomProvider provider, out IList schemaErrors, out Dictionary generatedViews)
{
//Create a CodeDomProvider based on options.
provider = null;
switch (m_languageOption)
{
case LanguageOption.GenerateCSharpCode:
provider = new Microsoft.CSharp.CSharpCodeProvider();
break;
case LanguageOption.GenerateVBCode:
provider = new Microsoft.VisualBasic.VBCodeProvider();
break;
}
//Get the views for the Entity Sets and Association Sets in the mapping item collection
GetViews(mappingCollection, out schemaErrors, out generatedViews);
}
private static void GetViews(StorageMappingItemCollection mappingCollection,
out IList schemaErrors, out Dictionary generatedViews)
{
generatedViews = mappingCollection.GetViews(out schemaErrors);
}
///
/// Generates the code to store the views in a C# or a VB file based on the
/// options passed in by the user.
///
///
///
///
///
///
private static void GenerateAndStoreViews(StorageMappingItemCollection mappingCollection,
Dictionary generatedViews, TextWriter sourceWriter, CodeDomProvider provider, IList schemaErrors)
{
EdmItemCollection edmCollection = mappingCollection.EdmItemCollection;
StoreItemCollection storeCollection = mappingCollection.StoreItemCollection;
//Create an emtpty compile unit and build up the generated code
CodeCompileUnit compileUnit = new CodeCompileUnit();
//Add the namespace for generated code
CodeNamespace codeNamespace = new CodeNamespace(EntityViewGenerationConstants.NamespaceName);
//Add copyright notice to the namespace comment.
compileUnit.Namespaces.Add(codeNamespace);
foreach (var storageEntityContainerMapping in mappingCollection.GetItems())
{
//Throw warning when containerMapping contains query view for bug 547285.
if (HasQueryView(storageEntityContainerMapping))
{
schemaErrors.Add(new EdmSchemaError(
Strings.UnsupportedQueryViewInEntityContainerMapping(storageEntityContainerMapping.Identity),
(int)StorageMappingErrorCode.UnsupportedQueryViewInEntityContainerMapping,
EdmSchemaErrorSeverity.Warning));
continue;
}
#region Class Declaration
string edmContainerName = storageEntityContainerMapping.EdmEntityContainer.Name;
string storeContainerName = storageEntityContainerMapping.StorageEntityContainer.Name;
string hashOverMappingClosure = MetadataMappingHasherVisitor.GetMappingClosureHash(edmCollection.EdmVersion, storageEntityContainerMapping);
StringBuilder inputForTypeNameContent = new StringBuilder(hashOverMappingClosure);
string viewStorageTypeName = EntityViewGenerationConstants.ViewGenerationTypeNamePrefix + StringHashBuilder.ComputeHash(MetadataHelper.CreateMetadataHashAlgorithm(edmCollection.EdmVersion), inputForTypeNameContent.ToString()).ToUpperInvariant();
//Add typeof expression to get the type that contains ViewGen type. This will help us in avoiding to go through
//all the types in the assembly. I have also verified that this works with VB with a root namespace prepended to the
//namespace since VB is picking up the type correctly as long as it is in the same assembly even with out the root namespace.
CodeTypeOfExpression viewGenTypeOfExpression = new CodeTypeOfExpression(EntityViewGenerationConstants.NamespaceName + "." + viewStorageTypeName);
//Add the assembly attribute that marks the assembly as the one that contains the generated views
CodeAttributeDeclaration viewGenAttribute = new CodeAttributeDeclaration(EntityViewGenerationConstants.ViewGenerationCustomAttributeName);
CodeAttributeArgument viewGenTypeArgument = new CodeAttributeArgument(viewGenTypeOfExpression);
viewGenAttribute.Arguments.Add(viewGenTypeArgument);
compileUnit.AssemblyCustomAttributes.Add(viewGenAttribute);
//Add the type which will be the class that contains all the views in this assembly
CodeTypeDeclaration viewStoringType = CreateTypeForStoringViews(viewStorageTypeName);
//Add the constructor, this will be the only method that this type will contain
//Create empty constructor.
CodeConstructor viewStoringTypeConstructor = CreateConstructorForViewStoringType();
viewStoringType.Attributes = MemberAttributes.Public;
//Get an expression that expresses this instance
CodeThisReferenceExpression thisRef = new CodeThisReferenceExpression();
string viewHash = MetadataHelper.GenerateHashForAllExtentViewsContent(edmCollection.EdmVersion, GenerateDictionaryForEntitySetNameAndView(generatedViews));
CodeAssignStatement EdmEntityContainerNameStatement =
new CodeAssignStatement(
new CodeFieldReferenceExpression(thisRef, EntityViewGenerationConstants.EdmEntityContainerName),
new CodePrimitiveExpression(edmContainerName));
CodeAssignStatement StoreEntityContainerNameStatement =
new CodeAssignStatement(
new CodeFieldReferenceExpression(thisRef, EntityViewGenerationConstants.StoreEntityContainerName),
new CodePrimitiveExpression(storeContainerName));
CodeAssignStatement HashOverMappingClosureStatement =
new CodeAssignStatement(
new CodeFieldReferenceExpression(thisRef, EntityViewGenerationConstants.HashOverMappingClosure),
new CodePrimitiveExpression(hashOverMappingClosure));
CodeAssignStatement HashOverAllExtentViewsStatement =
new CodeAssignStatement(
new CodeFieldReferenceExpression(thisRef, EntityViewGenerationConstants.HashOverAllExtentViews),
new CodePrimitiveExpression(viewHash));
CodeAssignStatement ViewCountStatement =
new CodeAssignStatement(
new CodeFieldReferenceExpression(thisRef, EntityViewGenerationConstants.ViewCountPropertyName),
new CodePrimitiveExpression(generatedViews.Count));
viewStoringTypeConstructor.Statements.Add(EdmEntityContainerNameStatement);
viewStoringTypeConstructor.Statements.Add(StoreEntityContainerNameStatement);
viewStoringTypeConstructor.Statements.Add(HashOverMappingClosureStatement);
viewStoringTypeConstructor.Statements.Add(HashOverAllExtentViewsStatement);
viewStoringTypeConstructor.Statements.Add(ViewCountStatement);
//Add the constructor to the type
viewStoringType.Members.Add(viewStoringTypeConstructor);
//Add the method to store views to the type
CreateAndAddGetViewAtMethod(viewStoringType, generatedViews);
//Add the type to the namespace
codeNamespace.Types.Add(viewStoringType);
#endregion
}
if (codeNamespace.Types.Count > 0)
{
GenerateCode(sourceWriter, provider, compileUnit);
sourceWriter.Flush();
}
}
private static bool HasQueryView(StorageEntityContainerMapping storageEntityContainerMapping)
{
foreach (EntitySetBase extent in storageEntityContainerMapping.EdmEntityContainer.BaseEntitySets)
{
if (storageEntityContainerMapping.HasQueryViewForSetMap(extent.Name))
{
return true;
}
}
return false;
}
private static Dictionary GenerateDictionaryForEntitySetNameAndView(Dictionary dictionary)
{
Dictionary newDictionary = new Dictionary();
foreach (var item in dictionary)
{
newDictionary.Add(GetExtentFullName(item.Key), item.Value);
}
return newDictionary;
}
///
/// Write code to the given stream from the compile unit.
///
///
///
///
private static void GenerateCode(TextWriter sourceWriter, CodeDomProvider provider, CodeCompileUnit compileUnit)
{
CodeGeneratorOptions styleOptions = new CodeGeneratorOptions();
styleOptions.BracingStyle = "C";
styleOptions.BlankLinesBetweenMembers = true;
styleOptions.VerbatimOrder = true;
provider.GenerateCodeFromCompileUnit(compileUnit, sourceWriter, styleOptions);
}
///
/// Generate Code to put the views in the generated code.
///
///
///
///
private static void CreateAndAddGetViewAtMethod(CodeTypeDeclaration typeDeclaration, Dictionary generatedViews)
{
//Add the views to a method
CodeMemberMethod getViewAtMethod = new CodeMemberMethod();
getViewAtMethod.Name = EntityViewGenerationConstants.GetViewAtMethodName;
getViewAtMethod.ReturnType = new CodeTypeReference(typeof(KeyValuePair<,>).MakeGenericType(new Type[] { typeof(string), typeof(string) }));
CodeParameterDeclarationExpression parameter = new CodeParameterDeclarationExpression(new CodeTypeReference(typeof(int)), "index");
getViewAtMethod.Parameters.Add(parameter);
getViewAtMethod.Comments.Add(new CodeCommentStatement(EntityViewGenerationConstants.SummaryStartElement, true /*docComment*/));
getViewAtMethod.Comments.Add(new CodeCommentStatement(Strings.GetViewAtMethodComments, true /*docComment*/));
getViewAtMethod.Comments.Add(new CodeCommentStatement(EntityViewGenerationConstants.SummaryEndElement, true /*docComment*/));
getViewAtMethod.Attributes = MemberAttributes.Family | MemberAttributes.Override;
typeDeclaration.Members.Add(getViewAtMethod);
int index = 0;
CodeVariableReferenceExpression indexParameterReference = new CodeVariableReferenceExpression(getViewAtMethod.Parameters[0].Name);
foreach (KeyValuePair generatedViewPair in generatedViews)
{
// the CodeDom does not support the following scenarios
// 1. switch statement
// 2. if(){} else if(){}
// The original design here was to have the following code,
// if() { else { if(){} } }
// but this had some drawbacks as described in TFS workitem 590996
// Given the not supported scenarios in CodeDom, we choose only use if statement in this case
// if(index == 0)
CodeConditionStatement currentIf = new CodeConditionStatement(new CodeBinaryOperatorExpression(
indexParameterReference, CodeBinaryOperatorType.ValueEquality, new CodePrimitiveExpression(index)));
getViewAtMethod.Statements.Add(currentIf);
EntitySetBase entitySet = generatedViewPair.Key;
string extentFullName = GetExtentFullName(entitySet);
CodeMemberMethod viewMethod = CreateViewReturnMethod(extentFullName, index, generatedViewPair.Value);
typeDeclaration.Members.Add(viewMethod);
// return GetNorthwindContext_Customers();
CodeMethodReturnStatement returnViewMethodCall = new CodeMethodReturnStatement(new CodeMethodInvokeExpression(new CodeMethodReferenceExpression(null, viewMethod.Name)));
currentIf.TrueStatements.Add(returnViewMethodCall);
index++;
}
// if an invalid index is asked for throw
getViewAtMethod.Statements.Add(new CodeThrowExceptionStatement(
new CodeObjectCreateExpression(new CodeTypeReference(typeof(IndexOutOfRangeException)))));
}
private static CodeMemberMethod CreateViewReturnMethod(string extentFullName, int index, string viewText)
{
//Add the views to a method
CodeMemberMethod viewMethod = new CodeMemberMethod();
viewMethod.Name = "GetView" + index.ToString();
viewMethod.Attributes = MemberAttributes.Private;
viewMethod.ReturnType = new CodeTypeReference(typeof(KeyValuePair<,>).MakeGenericType(new Type[] { typeof(string), typeof(string) }));
viewMethod.Comments.Add(new CodeCommentStatement(EntityViewGenerationConstants.SummaryStartElement, true /*docComment*/));
viewMethod.Comments.Add(new CodeCommentStatement(Strings.IndividualViewComments(extentFullName), true /*docComment*/));
viewMethod.Comments.Add(new CodeCommentStatement(EntityViewGenerationConstants.SummaryEndElement, true /*docComment*/));
CodeExpression viewTextExpression;
// only use the StringBuilder if we have to.
if (viewText.Length > MAXONELINELENGTH)
{
CreateSizedStringBuilder(viewMethod.Statements, viewText.Length);
foreach (var appendExpression in GetAppendViewStringsExpressions(viewText))
{
// viewString.Append(xxx);
viewMethod.Statements.Add(appendExpression);
}
viewTextExpression = new CodeMethodInvokeExpression(GetViewStringBuilderVariable(), "ToString");
}
else
{
viewTextExpression = new CodePrimitiveExpression(viewText);
}
// return new System.Collections.Generic.KeyValuePair("dbo.Products", viewString.ToString());
// or
// return new System.Collections.Generic.KeyValuePair("dbo.Products", "SELECT value c...");
CodeObjectCreateExpression newExpression =
new CodeObjectCreateExpression(
viewMethod.ReturnType,
new CodePrimitiveExpression(extentFullName),
viewTextExpression);
viewMethod.Statements.Add(new CodeMethodReturnStatement(newExpression));
return viewMethod;
}
private static void CreateSizedStringBuilder(CodeStatementCollection statements, int capacity)
{
// StringBuilder viewString = new StringBuilder(237);
CodeVariableDeclarationStatement viewStringDeclaration = new CodeVariableDeclarationStatement(typeof(StringBuilder), "viewString");
CodeObjectCreateExpression viewStringConstruct = new CodeObjectCreateExpression(typeof(StringBuilder), new CodePrimitiveExpression(capacity));
viewStringDeclaration.InitExpression = viewStringConstruct;
statements.Add(viewStringDeclaration);
}
private static IEnumerable SplitViewStrings(string largeViewString)
{
for (int i = 0; i <= largeViewString.Length / ONELINELENGTH; i++)
{
if (i * ONELINELENGTH + ONELINELENGTH < largeViewString.Length)
{
yield return largeViewString.Substring(i * ONELINELENGTH, ONELINELENGTH);
}
else
{
// the very last part of the splited string
yield return largeViewString.Substring(i * ONELINELENGTH);
}
}
}
private static IEnumerable GetViewStringsAppendToStringBuilder(
params string[] viewStrings)
{
foreach (var viewString in viewStrings)
{
// viewString.Append("xxx");
yield return AppendStringToStringBuilder(GetViewStringBuilderVariable(), viewString);
}
}
private static CodeVariableReferenceExpression GetViewStringBuilderVariable()
{
return new CodeVariableReferenceExpression("viewString");
}
private static CodeMethodInvokeExpression AppendStringToStringBuilder(
CodeVariableReferenceExpression stringBuilder, string stringToAppend)
{
return new CodeMethodInvokeExpression(
stringBuilder, "Append", new CodePrimitiveExpression(stringToAppend));
}
private static IEnumerable GetAppendViewStringsExpressions(string viewString)
{
if (viewString.Length > MAXONELINELENGTH)
{
// if the string is longer than 2046 charactors, we splitted them in to 80 each
// and append them using StringBuilder
return GetViewStringsAppendToStringBuilder(SplitViewStrings(viewString).ToArray());
}
else
{
return GetViewStringsAppendToStringBuilder(viewString);
}
}
private static string GetExtentFullName(EntitySetBase entitySet)
{
//We store the full Extent Name in the generated code which is
//EntityContainer name + "." + entitysetName
return entitySet.EntityContainer.Name + EntityViewGenerationConstants.QualificationCharacter + entitySet.Name;
}
///
/// Get the constructor for the type that will contain the generated views
///
///
private static CodeConstructor CreateConstructorForViewStoringType()
{
CodeConstructor constructor = new CodeConstructor();
//Mark it as public
constructor.Attributes = MemberAttributes.Public;
//Add constructor comments
constructor.Comments.Add(new CodeCommentStatement(EntityViewGenerationConstants.SummaryStartElement, true /*docComment*/));
constructor.Comments.Add(new CodeCommentStatement(Strings.ConstructorComments, true /*docComment*/));
constructor.Comments.Add(new CodeCommentStatement(EntityViewGenerationConstants.SummaryEndElement, true /*docComment*/));
return constructor;
}
///
/// Get the type declaration for the type that will contain the views.
///
///
private static CodeTypeDeclaration CreateTypeForStoringViews(string viewStorageTypeName)
{
CodeTypeDeclaration typeDecl = new CodeTypeDeclaration(viewStorageTypeName);
typeDecl.TypeAttributes = TypeAttributes.Sealed | TypeAttributes.Public;
//This type should derive from the framework type EntityViewContainer which reduces the amount
//of generated code
typeDecl.BaseTypes.Add(EntityViewGenerationConstants.BaseTypeName);
//Add type comments
typeDecl.Comments.Add(new CodeCommentStatement(EntityViewGenerationConstants.SummaryStartElement, true /*docComment*/));
typeDecl.Comments.Add(new CodeCommentStatement(Strings.TypeComments, true /*docComment*/));
typeDecl.Comments.Add(new CodeCommentStatement(EntityViewGenerationConstants.SummaryEndElement, true /*docComment*/));
return typeDecl;
}
#endregion
}
}
// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
Link Menu

This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- IfJoinedCondition.cs
- RepeatBehaviorConverter.cs
- DbDataReader.cs
- PerspectiveCamera.cs
- HttpWebRequestElement.cs
- RSAPKCS1KeyExchangeFormatter.cs
- DataGridCell.cs
- TrackingValidationObjectDictionary.cs
- Byte.cs
- ConfigXmlCDataSection.cs
- TextContainer.cs
- FrameworkContextData.cs
- EnumType.cs
- RegistryPermission.cs
- ValidationSummary.cs
- ShaderRenderModeValidation.cs
- ConfigXmlDocument.cs
- DbConvert.cs
- PreservationFileReader.cs
- XmlHierarchicalEnumerable.cs
- HttpServerUtilityBase.cs
- CalendarDataBindingHandler.cs
- UIElement3D.cs
- ColorConvertedBitmap.cs
- DataGridViewButtonCell.cs
- FilteredAttributeCollection.cs
- SqlDataSourceParameterParser.cs
- Blend.cs
- ImageSource.cs
- WebDescriptionAttribute.cs
- CodeTypeReferenceExpression.cs
- CatalogPart.cs
- CharAnimationBase.cs
- AnonymousIdentificationModule.cs
- UnhandledExceptionEventArgs.cs
- CookielessHelper.cs
- WsatAdminException.cs
- TimeStampChecker.cs
- SynchronizationContext.cs
- DrawingContextWalker.cs
- PasswordTextNavigator.cs
- DoubleAnimationUsingPath.cs
- SqlRowUpdatingEvent.cs
- DynamicResourceExtensionConverter.cs
- SystemColorTracker.cs
- _FixedSizeReader.cs
- MeasureItemEvent.cs
- ControlType.cs
- ProcessInputEventArgs.cs
- EventWaitHandleSecurity.cs
- BoundPropertyEntry.cs
- TextureBrush.cs
- QilPatternFactory.cs
- CollectionBase.cs
- ToolStripProfessionalLowResolutionRenderer.cs
- EntityContainerRelationshipSetEnd.cs
- HashCryptoHandle.cs
- AuthenticationModuleElement.cs
- TreeChangeInfo.cs
- BitmapEffectvisualstate.cs
- HotSpotCollection.cs
- HtmlElement.cs
- WorkflowOperationInvoker.cs
- sortedlist.cs
- NamedPipeConnectionPoolSettingsElement.cs
- ReferencedAssembly.cs
- TokenizerHelper.cs
- CroppedBitmap.cs
- PeerInvitationResponse.cs
- InitializationEventAttribute.cs
- TemplateInstanceAttribute.cs
- ComplexType.cs
- SafeTimerHandle.cs
- TextProperties.cs
- GridViewDeletedEventArgs.cs
- XmlSubtreeReader.cs
- ClientApiGenerator.cs
- HtmlTitle.cs
- SortQueryOperator.cs
- CancellationScope.cs
- ObjectParameter.cs
- ValidationHelpers.cs
- Listen.cs
- FormsAuthenticationCredentials.cs
- UIAgentCrashedException.cs
- StylusOverProperty.cs
- RequestNavigateEventArgs.cs
- FormViewDesigner.cs
- MetadataConversionError.cs
- LoginUtil.cs
- BrowserDefinition.cs
- WebBrowserSiteBase.cs
- AutomationIdentifierGuids.cs
- SetterBase.cs
- CopyOfAction.cs
- PaperSource.cs
- odbcmetadatacollectionnames.cs
- WpfKnownMemberInvoker.cs
- StreamGeometry.cs
- ProviderSettingsCollection.cs