Code:
/ Dotnetfx_Vista_SP2 / Dotnetfx_Vista_SP2 / 8.0.50727.4016 / DEVDIV / depot / DevDiv / releases / Orcas / QFE / ndp / fx / src / DLinq / Dlinq / DataShape.cs / 1 / DataShape.cs
using System;
using System.Collections.Generic;
using System.Text;
using System.Reflection;
using System.Linq;
using System.Linq.Expressions;
using System.Collections;
using System.Data.Linq.SqlClient;
using System.Diagnostics.CodeAnalysis;
namespace System.Data.Linq {
sealed public class DataLoadOptions {
bool frozen;
Dictionary includes = new Dictionary();
Dictionary subqueries = new Dictionary();
///
/// Describe a property that is automatically loaded when the containing instance is loaded
///
[SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "[....]: Generic types are an important part of Linq APIs and they could not exist without nested generic support.")]
[SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters", Justification = "[....]: Need to provide static typing.")]
public void LoadWith(Expression> expression) {
if (expression == null) {
throw Error.ArgumentNull("expression");
}
MemberInfo mi = GetLoadWithMemberInfo(expression);
this.Preload(mi);
}
///
/// Describe a property that is automatically loaded when the containing instance is loaded
///
public void LoadWith(LambdaExpression expression) {
if (expression == null) {
throw Error.ArgumentNull("expression");
}
MemberInfo mi = GetLoadWithMemberInfo(expression);
this.Preload(mi);
}
///
/// Place a subquery on the given association.
///
[SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "[....]: Generic types are an important part of Linq APIs and they could not exist without nested generic support.")]
[SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters", Justification = "[....]: Need to provide static typing.")]
public void AssociateWith(Expression> expression) {
if (expression == null) {
throw Error.ArgumentNull("expression");
}
this.AssociateWithInternal(expression);
}
///
/// Place a subquery on the given association.
///
public void AssociateWith(LambdaExpression expression) {
if (expression == null) {
throw Error.ArgumentNull("expression");
}
this.AssociateWithInternal(expression);
}
private void AssociateWithInternal(LambdaExpression expression) {
// Strip the cast-to-object.
Expression op = expression.Body;
while (op.NodeType == ExpressionType.Convert || op.NodeType == ExpressionType.ConvertChecked) {
op = ((UnaryExpression)op).Operand;
}
LambdaExpression lambda = Expression.Lambda(op, expression.Parameters.ToArray());
MemberInfo mi = Searcher.MemberInfoOf(lambda);
this.Subquery(mi, lambda);
}
///
/// Determines if the member is automatically loaded with its containing instances.
///
/// The member this is automatically loaded.
/// True if the member is automatically loaded.
internal bool IsPreloaded(MemberInfo member) {
if (member == null) {
throw Error.ArgumentNull("member");
}
return includes.ContainsKey(new MetaPosition(member));
}
///
/// Gets the subquery expression associated with the member.
///
/// The member with the subquery.
///
internal LambdaExpression GetAssociationSubquery(MemberInfo member) {
if (member == null) {
throw Error.ArgumentNull("member");
}
LambdaExpression expression = null;
subqueries.TryGetValue(new MetaPosition(member), out expression);
return expression;
}
///
/// Freeze the shape. Any further attempts to modify the shape will result in
/// an exception.
///
internal void Freeze() {
this.frozen = true;
}
///
/// Describe a property that is automatically loaded when the containing instance is loaded
///
internal void Preload(MemberInfo association) {
if (association == null) {
throw Error.ArgumentNull("association");
}
if (this.frozen) {
throw Error.IncludeNotAllowedAfterFreeze();
}
this.includes.Add(new MetaPosition(association), association);
ValidateTypeGraphAcyclic();
}
///
/// Place a subquery on the given association.
///
private void Subquery(MemberInfo association, LambdaExpression subquery) {
if (this.frozen) {
throw Error.SubqueryNotAllowedAfterFreeze();
}
subquery = (LambdaExpression)System.Data.Linq.SqlClient.Funcletizer.Funcletize(subquery); // Layering violation.
ValidateSubqueryMember(association);
ValidateSubqueryExpression(subquery);
this.subqueries[new MetaPosition(association)] = subquery;
}
///
/// If the lambda specified is of the form p.A, where p is the parameter
/// and A is a member on p, the MemberInfo for A is returned. If
/// the expression is not of this form, an exception is thrown.
///
private static MemberInfo GetLoadWithMemberInfo(LambdaExpression lambda)
{
// When the specified member is a value type, there will be a conversion
// to object that we need to strip
Expression body = lambda.Body;
if (body != null && (body.NodeType == ExpressionType.Convert || body.NodeType == ExpressionType.ConvertChecked))
{
body = ((UnaryExpression)body).Operand;
}
MemberExpression mex = body as MemberExpression;
if (mex != null && mex.Expression.NodeType == ExpressionType.Parameter)
{
return mex.Member;
}
else
{
throw Error.InvalidLoadOptionsLoadMemberSpecification();
}
}
private static class Searcher {
static internal MemberInfo MemberInfoOf(LambdaExpression lambda) {
Visitor v = new Visitor();
v.VisitLambda(lambda);
return v.MemberInfo;
}
private class Visitor : System.Data.Linq.SqlClient.ExpressionVisitor {
internal MemberInfo MemberInfo;
internal override Expression VisitMemberAccess(MemberExpression m) {
this.MemberInfo = m.Member;
return base.VisitMemberAccess(m);
}
internal override Expression VisitMethodCall(MethodCallExpression m) {
this.Visit(m.Object);
foreach (Expression arg in m.Arguments) {
this.Visit(arg);
break; // Only follow the extension method 'this'
}
return m;
}
}
}
private void ValidateTypeGraphAcyclic() {
IEnumerable edges = this.includes.Values;
int removed = 0;
for (int loop = 0; loop < this.includes.Count; ++loop) {
// Build a list of all edge targets.
HashSet edgeTargets = new HashSet();
foreach (MemberInfo edge in edges) {
edgeTargets.Add(GetIncludeTarget(edge));
}
// Remove all edges with sources matching no target.
List newEdges = new List();
bool someRemoved = false;
foreach (MemberInfo edge in edges) {
if (edgeTargets.Where(et=>et.IsAssignableFrom(edge.DeclaringType) || edge.DeclaringType.IsAssignableFrom(et)).Any()) {
newEdges.Add(edge);
}
else {
++removed;
someRemoved = true;
if (removed == this.includes.Count)
return;
}
}
if (!someRemoved) {
throw Error.IncludeCycleNotAllowed(); // No edges removed, there must be a loop.
}
edges = newEdges;
}
throw new InvalidOperationException("Bug in ValidateTypeGraphAcyclic"); // Getting here means a bug.
}
private static Type GetIncludeTarget(MemberInfo mi) {
Type mt = System.Data.Linq.SqlClient.TypeSystem.GetMemberType(mi);
if (mt.IsGenericType) {
return mt.GetGenericArguments()[0];
}
return mt;
}
private static void ValidateSubqueryMember(MemberInfo mi) {
Type memberType = System.Data.Linq.SqlClient.TypeSystem.GetMemberType(mi);
if (memberType == null) {
throw Error.SubqueryNotSupportedOn(mi);
}
if (!typeof(IEnumerable).IsAssignableFrom(memberType)) {
throw Error.SubqueryNotSupportedOnType(mi.Name, mi.DeclaringType);
}
}
private static void ValidateSubqueryExpression(LambdaExpression subquery) {
if (!typeof(IEnumerable).IsAssignableFrom(subquery.Body.Type)) {
throw Error.SubqueryMustBeSequence();
}
new SubqueryValidator().VisitLambda(subquery);
}
///
/// Ensure that the subquery follows the rules for subqueries.
///
private class SubqueryValidator : System.Data.Linq.SqlClient.ExpressionVisitor {
bool isTopLevel = true;
internal override Expression VisitMethodCall(MethodCallExpression m) {
bool was = isTopLevel;
try {
if (isTopLevel && !SubqueryRules.IsSupportedTopLevelMethod(m.Method))
throw Error.SubqueryDoesNotSupportOperator(m.Method.Name);
isTopLevel = false;
return base.VisitMethodCall(m);
}
finally {
isTopLevel = was;
}
}
}
///
/// Whether there have been LoadOptions specified.
///
internal bool IsEmpty {
get { return this.includes.Count == 0 && this.subqueries.Count == 0; }
}
}
}
// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.
using System;
using System.Collections.Generic;
using System.Text;
using System.Reflection;
using System.Linq;
using System.Linq.Expressions;
using System.Collections;
using System.Data.Linq.SqlClient;
using System.Diagnostics.CodeAnalysis;
namespace System.Data.Linq {
sealed public class DataLoadOptions {
bool frozen;
Dictionary includes = new Dictionary();
Dictionary subqueries = new Dictionary();
///
/// Describe a property that is automatically loaded when the containing instance is loaded
///
[SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "[....]: Generic types are an important part of Linq APIs and they could not exist without nested generic support.")]
[SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters", Justification = "[....]: Need to provide static typing.")]
public void LoadWith(Expression> expression) {
if (expression == null) {
throw Error.ArgumentNull("expression");
}
MemberInfo mi = GetLoadWithMemberInfo(expression);
this.Preload(mi);
}
///
/// Describe a property that is automatically loaded when the containing instance is loaded
///
public void LoadWith(LambdaExpression expression) {
if (expression == null) {
throw Error.ArgumentNull("expression");
}
MemberInfo mi = GetLoadWithMemberInfo(expression);
this.Preload(mi);
}
///
/// Place a subquery on the given association.
///
[SuppressMessage("Microsoft.Design", "CA1006:DoNotNestGenericTypesInMemberSignatures", Justification = "[....]: Generic types are an important part of Linq APIs and they could not exist without nested generic support.")]
[SuppressMessage("Microsoft.Design", "CA1011:ConsiderPassingBaseTypesAsParameters", Justification = "[....]: Need to provide static typing.")]
public void AssociateWith(Expression> expression) {
if (expression == null) {
throw Error.ArgumentNull("expression");
}
this.AssociateWithInternal(expression);
}
///
/// Place a subquery on the given association.
///
public void AssociateWith(LambdaExpression expression) {
if (expression == null) {
throw Error.ArgumentNull("expression");
}
this.AssociateWithInternal(expression);
}
private void AssociateWithInternal(LambdaExpression expression) {
// Strip the cast-to-object.
Expression op = expression.Body;
while (op.NodeType == ExpressionType.Convert || op.NodeType == ExpressionType.ConvertChecked) {
op = ((UnaryExpression)op).Operand;
}
LambdaExpression lambda = Expression.Lambda(op, expression.Parameters.ToArray());
MemberInfo mi = Searcher.MemberInfoOf(lambda);
this.Subquery(mi, lambda);
}
///
/// Determines if the member is automatically loaded with its containing instances.
///
/// The member this is automatically loaded.
/// True if the member is automatically loaded.
internal bool IsPreloaded(MemberInfo member) {
if (member == null) {
throw Error.ArgumentNull("member");
}
return includes.ContainsKey(new MetaPosition(member));
}
///
/// Gets the subquery expression associated with the member.
///
/// The member with the subquery.
///
internal LambdaExpression GetAssociationSubquery(MemberInfo member) {
if (member == null) {
throw Error.ArgumentNull("member");
}
LambdaExpression expression = null;
subqueries.TryGetValue(new MetaPosition(member), out expression);
return expression;
}
///
/// Freeze the shape. Any further attempts to modify the shape will result in
/// an exception.
///
internal void Freeze() {
this.frozen = true;
}
///
/// Describe a property that is automatically loaded when the containing instance is loaded
///
internal void Preload(MemberInfo association) {
if (association == null) {
throw Error.ArgumentNull("association");
}
if (this.frozen) {
throw Error.IncludeNotAllowedAfterFreeze();
}
this.includes.Add(new MetaPosition(association), association);
ValidateTypeGraphAcyclic();
}
///
/// Place a subquery on the given association.
///
private void Subquery(MemberInfo association, LambdaExpression subquery) {
if (this.frozen) {
throw Error.SubqueryNotAllowedAfterFreeze();
}
subquery = (LambdaExpression)System.Data.Linq.SqlClient.Funcletizer.Funcletize(subquery); // Layering violation.
ValidateSubqueryMember(association);
ValidateSubqueryExpression(subquery);
this.subqueries[new MetaPosition(association)] = subquery;
}
///
/// If the lambda specified is of the form p.A, where p is the parameter
/// and A is a member on p, the MemberInfo for A is returned. If
/// the expression is not of this form, an exception is thrown.
///
private static MemberInfo GetLoadWithMemberInfo(LambdaExpression lambda)
{
// When the specified member is a value type, there will be a conversion
// to object that we need to strip
Expression body = lambda.Body;
if (body != null && (body.NodeType == ExpressionType.Convert || body.NodeType == ExpressionType.ConvertChecked))
{
body = ((UnaryExpression)body).Operand;
}
MemberExpression mex = body as MemberExpression;
if (mex != null && mex.Expression.NodeType == ExpressionType.Parameter)
{
return mex.Member;
}
else
{
throw Error.InvalidLoadOptionsLoadMemberSpecification();
}
}
private static class Searcher {
static internal MemberInfo MemberInfoOf(LambdaExpression lambda) {
Visitor v = new Visitor();
v.VisitLambda(lambda);
return v.MemberInfo;
}
private class Visitor : System.Data.Linq.SqlClient.ExpressionVisitor {
internal MemberInfo MemberInfo;
internal override Expression VisitMemberAccess(MemberExpression m) {
this.MemberInfo = m.Member;
return base.VisitMemberAccess(m);
}
internal override Expression VisitMethodCall(MethodCallExpression m) {
this.Visit(m.Object);
foreach (Expression arg in m.Arguments) {
this.Visit(arg);
break; // Only follow the extension method 'this'
}
return m;
}
}
}
private void ValidateTypeGraphAcyclic() {
IEnumerable edges = this.includes.Values;
int removed = 0;
for (int loop = 0; loop < this.includes.Count; ++loop) {
// Build a list of all edge targets.
HashSet edgeTargets = new HashSet();
foreach (MemberInfo edge in edges) {
edgeTargets.Add(GetIncludeTarget(edge));
}
// Remove all edges with sources matching no target.
List newEdges = new List();
bool someRemoved = false;
foreach (MemberInfo edge in edges) {
if (edgeTargets.Where(et=>et.IsAssignableFrom(edge.DeclaringType) || edge.DeclaringType.IsAssignableFrom(et)).Any()) {
newEdges.Add(edge);
}
else {
++removed;
someRemoved = true;
if (removed == this.includes.Count)
return;
}
}
if (!someRemoved) {
throw Error.IncludeCycleNotAllowed(); // No edges removed, there must be a loop.
}
edges = newEdges;
}
throw new InvalidOperationException("Bug in ValidateTypeGraphAcyclic"); // Getting here means a bug.
}
private static Type GetIncludeTarget(MemberInfo mi) {
Type mt = System.Data.Linq.SqlClient.TypeSystem.GetMemberType(mi);
if (mt.IsGenericType) {
return mt.GetGenericArguments()[0];
}
return mt;
}
private static void ValidateSubqueryMember(MemberInfo mi) {
Type memberType = System.Data.Linq.SqlClient.TypeSystem.GetMemberType(mi);
if (memberType == null) {
throw Error.SubqueryNotSupportedOn(mi);
}
if (!typeof(IEnumerable).IsAssignableFrom(memberType)) {
throw Error.SubqueryNotSupportedOnType(mi.Name, mi.DeclaringType);
}
}
private static void ValidateSubqueryExpression(LambdaExpression subquery) {
if (!typeof(IEnumerable).IsAssignableFrom(subquery.Body.Type)) {
throw Error.SubqueryMustBeSequence();
}
new SubqueryValidator().VisitLambda(subquery);
}
///
/// Ensure that the subquery follows the rules for subqueries.
///
private class SubqueryValidator : System.Data.Linq.SqlClient.ExpressionVisitor {
bool isTopLevel = true;
internal override Expression VisitMethodCall(MethodCallExpression m) {
bool was = isTopLevel;
try {
if (isTopLevel && !SubqueryRules.IsSupportedTopLevelMethod(m.Method))
throw Error.SubqueryDoesNotSupportOperator(m.Method.Name);
isTopLevel = false;
return base.VisitMethodCall(m);
}
finally {
isTopLevel = was;
}
}
}
///
/// Whether there have been LoadOptions specified.
///
internal bool IsEmpty {
get { return this.includes.Count == 0 && this.subqueries.Count == 0; }
}
}
}
// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.
Link Menu

This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- Pointer.cs
- TraceUtility.cs
- QilGeneratorEnv.cs
- ArraySubsetEnumerator.cs
- PropertyValueChangedEvent.cs
- FixUpCollection.cs
- XmlWrappingWriter.cs
- TokenizerHelper.cs
- __ComObject.cs
- EditingCommands.cs
- WebExceptionStatus.cs
- ISAPIWorkerRequest.cs
- MenuItemBinding.cs
- HttpModuleAction.cs
- RuleSet.cs
- LayeredChannelListener.cs
- DataGridItemCollection.cs
- TabItem.cs
- Literal.cs
- IpcChannel.cs
- BoolExpression.cs
- PathFigureCollection.cs
- XmlHierarchicalDataSourceView.cs
- WindowsStatusBar.cs
- DrawToolTipEventArgs.cs
- OletxDependentTransaction.cs
- HostingEnvironmentSection.cs
- LoginCancelEventArgs.cs
- WinFormsSpinner.cs
- SoapCommonClasses.cs
- SafeRightsManagementQueryHandle.cs
- CopyNodeSetAction.cs
- RelationshipFixer.cs
- ISFTagAndGuidCache.cs
- Synchronization.cs
- ThreadExceptionDialog.cs
- PageRanges.cs
- EFDataModelProvider.cs
- CSharpCodeProvider.cs
- GeneratedContractType.cs
- SemaphoreFullException.cs
- X509ClientCertificateCredentialsElement.cs
- RankException.cs
- ExtenderProvidedPropertyAttribute.cs
- BufferAllocator.cs
- OutputCacheProviderCollection.cs
- QuerySafeNavigator.cs
- GridLength.cs
- DataRowCollection.cs
- DataGridPageChangedEventArgs.cs
- UserControlCodeDomTreeGenerator.cs
- StylusPointCollection.cs
- XmlDomTextWriter.cs
- Typeface.cs
- WindowsServiceElement.cs
- NativeMethods.cs
- StateWorkerRequest.cs
- ShaderEffect.cs
- DataGridViewRowCancelEventArgs.cs
- OptionalRstParameters.cs
- ResourceProviderFactory.cs
- MarshalDirectiveException.cs
- DecoderBestFitFallback.cs
- Knowncolors.cs
- ViewGenResults.cs
- ExtensionQuery.cs
- DataGridViewRowCollection.cs
- Comparer.cs
- NetworkInterface.cs
- DocumentStatusResources.cs
- MultiByteCodec.cs
- RequestChannel.cs
- DbExpressionBuilder.cs
- TextRangeEditTables.cs
- BidirectionalDictionary.cs
- DataObjectAttribute.cs
- RadioButton.cs
- NoPersistProperty.cs
- TypeResolvingOptionsAttribute.cs
- WmlMobileTextWriter.cs
- ObjectStateEntry.cs
- AnnotationResourceCollection.cs
- CodeNamespaceCollection.cs
- SafeArrayRankMismatchException.cs
- DataColumnPropertyDescriptor.cs
- SoapTransportImporter.cs
- XamlFrame.cs
- MethodToken.cs
- SchemaType.cs
- indexingfiltermarshaler.cs
- SqlCacheDependencySection.cs
- MsmqDiagnostics.cs
- Manipulation.cs
- BinaryObjectWriter.cs
- ParameterToken.cs
- NameValueCollection.cs
- HttpServerUtilityBase.cs
- DesignSurfaceServiceContainer.cs
- DocumentSequenceHighlightLayer.cs
- X509RawDataKeyIdentifierClause.cs