You've already forked linux-packaging-mono
Imported Upstream version 4.6.0.125
Former-commit-id: a2155e9bd80020e49e72e86c44da02a8ac0e57a4
This commit is contained in:
parent
a569aebcfd
commit
e79aa3c0ed
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,57 @@
|
||||
//---------------------------------------------------------------------
|
||||
// <copyright file="EntityDataSourceChangedEventArgs.cs" company="Microsoft">
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// </copyright>
|
||||
//
|
||||
// @owner [....]
|
||||
// @backupOwner objsdev
|
||||
//---------------------------------------------------------------------
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Data.Objects;
|
||||
|
||||
namespace System.Web.UI.WebControls
|
||||
{
|
||||
public class EntityDataSourceChangedEventArgs : EventArgs
|
||||
{
|
||||
private readonly ObjectContext _context;
|
||||
private readonly Exception _exception = null;
|
||||
private bool _exceptionHandled = false;
|
||||
private readonly object _entity = null;
|
||||
|
||||
internal EntityDataSourceChangedEventArgs(ObjectContext context, object entity)
|
||||
{
|
||||
_context = context;
|
||||
_entity = entity;
|
||||
}
|
||||
|
||||
internal EntityDataSourceChangedEventArgs(Exception exception)
|
||||
{
|
||||
_exception = exception;
|
||||
}
|
||||
|
||||
public Exception Exception
|
||||
{
|
||||
get { return _exception; }
|
||||
}
|
||||
|
||||
public bool ExceptionHandled
|
||||
{
|
||||
get { return _exceptionHandled; }
|
||||
set { _exceptionHandled = value; }
|
||||
}
|
||||
|
||||
public object Entity
|
||||
{
|
||||
get { return _entity; }
|
||||
}
|
||||
|
||||
public ObjectContext Context
|
||||
{
|
||||
get { return _context; }
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,57 @@
|
||||
//---------------------------------------------------------------------
|
||||
// <copyright file="EntityDataSourceChangingEventArgs.cs" company="Microsoft">
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// </copyright>
|
||||
//
|
||||
// @owner [....]
|
||||
// @backupOwner objsdev
|
||||
//---------------------------------------------------------------------
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Data.Objects;
|
||||
|
||||
namespace System.Web.UI.WebControls
|
||||
{
|
||||
public class EntityDataSourceChangingEventArgs : System.ComponentModel.CancelEventArgs
|
||||
{
|
||||
private readonly ObjectContext _context;
|
||||
private readonly Exception _exception = null;
|
||||
private bool _exceptionHandled = false;
|
||||
private readonly object _entity = null;
|
||||
|
||||
internal EntityDataSourceChangingEventArgs(ObjectContext context, object entity)
|
||||
{
|
||||
_context = context;
|
||||
_entity = entity;
|
||||
}
|
||||
|
||||
internal EntityDataSourceChangingEventArgs(Exception exception)
|
||||
{
|
||||
_exception = exception;
|
||||
}
|
||||
|
||||
public Exception Exception
|
||||
{
|
||||
get { return _exception; }
|
||||
}
|
||||
|
||||
public bool ExceptionHandled
|
||||
{
|
||||
get { return _exceptionHandled; }
|
||||
set { _exceptionHandled = value; }
|
||||
}
|
||||
|
||||
public object Entity
|
||||
{
|
||||
get { return _entity; }
|
||||
}
|
||||
|
||||
public ObjectContext Context
|
||||
{
|
||||
get { return _context; }
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,441 @@
|
||||
//---------------------------------------------------------------------
|
||||
// <copyright file="EntityDataSourceColumn.cs" company="Microsoft">
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// </copyright>
|
||||
//
|
||||
// @owner [....]
|
||||
// @backupOwner [....]
|
||||
//---------------------------------------------------------------------
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Data.EntityClient;
|
||||
using System.Data.Metadata.Edm;
|
||||
using System.Diagnostics;
|
||||
using System.Globalization;
|
||||
using System.Reflection;
|
||||
using System.ComponentModel;
|
||||
using System.Data.Common;
|
||||
using System.Data.Objects.DataClasses;
|
||||
using System.Data.Objects;
|
||||
using System.Data;
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
namespace System.Web.UI.WebControls
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a column in EntityDataSourceView.
|
||||
/// </summary>
|
||||
internal abstract class EntityDataSourceColumn
|
||||
{
|
||||
protected EntityDataSourceColumn(string displayName)
|
||||
: this(displayName, (EntityDataSourceColumn)null)
|
||||
{
|
||||
}
|
||||
|
||||
protected EntityDataSourceColumn(string displayName, EntityDataSourceColumn controllingColumn)
|
||||
{
|
||||
EntityDataSourceUtil.CheckArgumentNull(displayName, "displayName");
|
||||
|
||||
this.DisplayName = displayName;
|
||||
this.ControllingColumn = controllingColumn;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the display name for this column.
|
||||
/// </summary>
|
||||
internal readonly string DisplayName;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the column exposed to the user. For instance, the reference key
|
||||
/// it.Order.OrderID might have a dependent it.OrderID where there is a
|
||||
/// ReferentialConstraint.
|
||||
/// </summary>
|
||||
internal readonly EntityDataSourceColumn ControllingColumn;
|
||||
|
||||
/// <summary>
|
||||
/// Gets value indicating whether the column should be exposed to the user.
|
||||
/// </summary>
|
||||
internal bool IsHidden
|
||||
{
|
||||
get
|
||||
{
|
||||
// Columns with dependents are not shown to the user. They are
|
||||
// merely used to plumb values (e.g. via referential integrity
|
||||
// constraints)
|
||||
return this.ControllingColumn != null;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the CLR type for the column value.
|
||||
/// </summary>
|
||||
internal abstract Type ClrType { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether the original value for the column
|
||||
/// needs to be preserved.
|
||||
/// </summary>
|
||||
internal abstract bool IsInteresting { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether the column can be modified. Can be
|
||||
/// overridden by the collection (which may be readonly).
|
||||
/// </summary>
|
||||
internal abstract bool CanWrite { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether this column can be assigned a value of null.
|
||||
/// </summary>
|
||||
internal abstract bool IsNullable { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether this column represents a scalar type.
|
||||
/// </summary>
|
||||
internal abstract bool IsScalar { get; }
|
||||
|
||||
/// Returns an Entity-SQL representation of this column with respect
|
||||
/// to entity parameter 'it'.
|
||||
/// </summary>
|
||||
/// <returns>Entity-SQL string.</returns>
|
||||
internal abstract string GetEntitySqlValue();
|
||||
|
||||
internal abstract object GetValue(EntityDataSourceWrapper entity);
|
||||
internal abstract void SetValue(EntityDataSourceWrapper entity, object value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// An EntityDataSourceView column that is an entity type or complex type property.
|
||||
/// </summary>
|
||||
internal class EntityDataSourcePropertyColumn : EntityDataSourceColumn
|
||||
{
|
||||
private readonly EntityDataSourceMemberPath memberPath;
|
||||
|
||||
internal EntityDataSourcePropertyColumn(EntityDataSourceMemberPath memberPath)
|
||||
: base(EntityDataSourceUtil.CheckArgumentNull(memberPath, "memberPath").GetDescription())
|
||||
{
|
||||
this.memberPath = memberPath;
|
||||
}
|
||||
|
||||
internal override bool IsInteresting
|
||||
{
|
||||
get
|
||||
{
|
||||
// the member path knows if its interesting...
|
||||
return this.memberPath.IsInteresting;
|
||||
}
|
||||
}
|
||||
|
||||
internal override bool CanWrite
|
||||
{
|
||||
get
|
||||
{
|
||||
// can always write
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
internal override bool IsNullable
|
||||
{
|
||||
get { return memberPath.IsNullable; }
|
||||
}
|
||||
|
||||
internal override bool IsScalar
|
||||
{
|
||||
get { return memberPath.IsScalar; }
|
||||
}
|
||||
|
||||
internal override Type ClrType
|
||||
{
|
||||
get { return this.memberPath.ClrType; }
|
||||
}
|
||||
|
||||
override internal object GetValue(EntityDataSourceWrapper entity)
|
||||
{
|
||||
return this.memberPath.GetValue(entity);
|
||||
}
|
||||
|
||||
override internal void SetValue(EntityDataSourceWrapper entity, object value)
|
||||
{
|
||||
this.memberPath.SetValue(entity, value);
|
||||
}
|
||||
|
||||
internal override string GetEntitySqlValue()
|
||||
{
|
||||
return this.memberPath.GetEntitySqlValue();
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return this.memberPath.ToString();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether this column represents a primary key value;
|
||||
/// </summary>
|
||||
internal bool IsKey
|
||||
{
|
||||
get { return memberPath.IsKey; }
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// An EntityDataSourceView column
|
||||
/// </summary>
|
||||
internal class EntityDataSourceReferenceKeyColumn : EntityDataSourceColumn
|
||||
{
|
||||
private readonly EntityDataSourceReferenceGroup group;
|
||||
private readonly EdmProperty keyMember;
|
||||
private readonly Type clrType;
|
||||
private readonly bool isNullable;
|
||||
|
||||
internal EntityDataSourceReferenceKeyColumn(MetadataWorkspace workspace, EntityDataSourceReferenceGroup group, EdmProperty keyMember, EntityDataSourceColumn dependent)
|
||||
: base(CreateDisplayName(group, keyMember), dependent)
|
||||
{
|
||||
EntityDataSourceUtil.CheckArgumentNull(group, "group");
|
||||
EntityDataSourceUtil.CheckArgumentNull(keyMember, "keyMember");
|
||||
Debug.Assert(EntityDataSourceUtil.IsScalar(keyMember.TypeUsage.EdmType), "Expected primitive or enum type for key members.");
|
||||
|
||||
this.group = group;
|
||||
this.keyMember = keyMember;
|
||||
this.clrType = EntityDataSourceUtil.GetMemberClrType(workspace, keyMember);
|
||||
|
||||
// if the association end is optional (0..1), make sure the CLR type
|
||||
// is also nullable
|
||||
if (this.group.End.CorrespondingAssociationEndMember.RelationshipMultiplicity == RelationshipMultiplicity.ZeroOrOne)
|
||||
{
|
||||
this.clrType = EntityDataSourceUtil.MakeNullable(clrType);
|
||||
this.isNullable = true;
|
||||
}
|
||||
}
|
||||
|
||||
internal override bool IsInteresting
|
||||
{
|
||||
get
|
||||
{
|
||||
// references are always interesting
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
internal override bool CanWrite
|
||||
{
|
||||
get
|
||||
{
|
||||
// references can always be written
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
internal override bool IsNullable
|
||||
{
|
||||
get { return this.isNullable; }
|
||||
}
|
||||
|
||||
internal override bool IsScalar
|
||||
{
|
||||
get { return EntityDataSourceUtil.IsScalar(keyMember.TypeUsage.EdmType); }
|
||||
}
|
||||
|
||||
internal override Type ClrType
|
||||
{
|
||||
get { return this.clrType; }
|
||||
}
|
||||
|
||||
internal EntityDataSourceReferenceGroup Group
|
||||
{
|
||||
get { return this.group; }
|
||||
}
|
||||
|
||||
internal EdmMember KeyMember
|
||||
{
|
||||
get { return this.keyMember; }
|
||||
}
|
||||
|
||||
private static string CreateDisplayName(EntityDataSourceReferenceGroup group, EdmProperty keyMember)
|
||||
{
|
||||
EntityDataSourceUtil.CheckArgumentNull(group, "group");
|
||||
EntityDataSourceUtil.CheckArgumentNull(keyMember, "keyMember");
|
||||
|
||||
NavigationProperty navigationProperty;
|
||||
|
||||
string result;
|
||||
|
||||
if (EntityDataSourceUtil.TryGetCorrespondingNavigationProperty(group.End.CorrespondingAssociationEndMember, out navigationProperty))
|
||||
{
|
||||
result = navigationProperty.Name + "." + keyMember.Name;
|
||||
}
|
||||
else
|
||||
{
|
||||
// if there is no Navigation property, use the TargetTole and KeyMember name
|
||||
// TargetRole.KeyMember
|
||||
result = group.End.Name + "." + keyMember.Name;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return String.Format(CultureInfo.InvariantCulture, "<Set = {0}, Role = {1}>",
|
||||
this.group.End.ParentAssociationSet.Name, this.group.End.Name);
|
||||
}
|
||||
|
||||
internal override object GetValue(EntityDataSourceWrapper entity)
|
||||
{
|
||||
EntityKey entityKey = this.Group.GetEntityKey(entity);
|
||||
if (null == entityKey)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
else
|
||||
{
|
||||
object value = null;
|
||||
// loop through to find the correct keymember, take compound key into consideration
|
||||
foreach (EntityKeyMember entityKeyValue in entityKey.EntityKeyValues)
|
||||
{
|
||||
if (entityKeyValue.Key == this.KeyMember.Name)
|
||||
{
|
||||
value = entityKeyValue.Value;
|
||||
}
|
||||
}
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
internal override void SetValue(EntityDataSourceWrapper entity, object value)
|
||||
{
|
||||
throw new InvalidOperationException(Strings.SetValueNotSupported);
|
||||
}
|
||||
|
||||
internal override string GetEntitySqlValue()
|
||||
{
|
||||
// syntax: NAVIGATE(it, _association_type_name_, _target_role_name_)._key_member_
|
||||
StringBuilder builder = new StringBuilder();
|
||||
|
||||
builder.Append("NAVIGATE(");
|
||||
builder.Append(EntityDataSourceUtil.EntitySqlElementAlias);
|
||||
builder.Append(", ");
|
||||
builder.Append(EntityDataSourceUtil.CreateEntitySqlTypeIdentifier(this.Group.End.ParentAssociationSet.ElementType));
|
||||
builder.Append(", ");
|
||||
builder.Append(EntityDataSourceUtil.QuoteEntitySqlIdentifier(this.Group.End.CorrespondingAssociationEndMember.Name));
|
||||
builder.Append(").");
|
||||
builder.Append(EntityDataSourceUtil.QuoteEntitySqlIdentifier(this.keyMember.Name));
|
||||
string result = builder.ToString();
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
internal abstract class EntityDataSourceReferenceValueColumn : EntityDataSourceColumn
|
||||
{
|
||||
private readonly NavigationProperty navigationProperty;
|
||||
|
||||
protected EntityDataSourceReferenceValueColumn(MetadataWorkspace ocWorkspace, NavigationProperty navigationProperty)
|
||||
: base(EntityDataSourceUtil.CheckArgumentNull(navigationProperty, "navigationProperty").Name)
|
||||
{
|
||||
EntityDataSourceUtil.CheckArgumentNull(ocWorkspace, "ocWorkspace");
|
||||
|
||||
this.navigationProperty = navigationProperty;
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)]
|
||||
internal static EntityDataSourceReferenceValueColumn Create(Type clrToType, MetadataWorkspace ocWorkspace, NavigationProperty navigationProperty)
|
||||
{
|
||||
EntityDataSourceUtil.CheckArgumentNull(clrToType, "clrToType");
|
||||
|
||||
Type columnType = typeof(EntityDataSourceReferenceValueColumn<>).MakeGenericType(clrToType);
|
||||
EntityDataSourceReferenceValueColumn result = (EntityDataSourceReferenceValueColumn)Activator.CreateInstance(columnType, ocWorkspace, navigationProperty);
|
||||
return result;
|
||||
}
|
||||
|
||||
internal override bool CanWrite
|
||||
{
|
||||
get
|
||||
{
|
||||
// can never write to a navigation reference
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
internal override bool IsNullable
|
||||
{
|
||||
get { return navigationProperty.ToEndMember.RelationshipMultiplicity == RelationshipMultiplicity.ZeroOrOne; }
|
||||
}
|
||||
|
||||
protected NavigationProperty NavigationProperty
|
||||
{
|
||||
get { return this.navigationProperty; }
|
||||
}
|
||||
|
||||
internal override bool IsScalar
|
||||
{
|
||||
get { return false; }
|
||||
}
|
||||
|
||||
internal override string GetEntitySqlValue()
|
||||
{
|
||||
// it.NavigationPropertyName
|
||||
string result = EntityDataSourceUtil.EntitySqlElementAlias + "." + EntityDataSourceUtil.QuoteEntitySqlIdentifier(this.navigationProperty.Name);
|
||||
return result;
|
||||
}
|
||||
|
||||
internal override bool IsInteresting
|
||||
{
|
||||
get
|
||||
{
|
||||
// a navigation reference is not written, so its original values aren't interesting
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
internal override void SetValue(EntityDataSourceWrapper entity, object value)
|
||||
{
|
||||
throw new InvalidOperationException(Strings.SetValueNotSupported);
|
||||
}
|
||||
}
|
||||
|
||||
internal class EntityDataSourceReferenceValueColumn<T> : EntityDataSourceReferenceValueColumn
|
||||
where T : class
|
||||
{
|
||||
public EntityDataSourceReferenceValueColumn(MetadataWorkspace ocWorkspace, NavigationProperty navigationProperty)
|
||||
: base(ocWorkspace, navigationProperty)
|
||||
{
|
||||
}
|
||||
|
||||
internal override object GetValue(EntityDataSourceWrapper entity)
|
||||
{
|
||||
object result;
|
||||
EntityReference<T> reference = GetRelatedReference(entity);
|
||||
if (reference.IsLoaded)
|
||||
{
|
||||
result = reference.Value;
|
||||
}
|
||||
else
|
||||
{
|
||||
result = null;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
internal override Type ClrType
|
||||
{
|
||||
get
|
||||
{
|
||||
return typeof(T);
|
||||
}
|
||||
}
|
||||
|
||||
private EntityReference<T> GetRelatedReference(EntityDataSourceWrapper entity)
|
||||
{
|
||||
RelationshipManager relationshipManager = entity.RelationshipManager;
|
||||
Debug.Assert(relationshipManager != null, "Coldn't retrieve a RelationshipManager");
|
||||
EntityReference<T> reference = relationshipManager.GetRelatedReference<T>(
|
||||
this.NavigationProperty.RelationshipType.FullName,
|
||||
this.NavigationProperty.ToEndMember.Name);
|
||||
return reference;
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,29 @@
|
||||
//---------------------------------------------------------------------
|
||||
// <copyright file="EntityDataSourceContextCreatedEventArgs.cs" company="Microsoft">
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// </copyright>
|
||||
//
|
||||
// @owner [....]
|
||||
// @backupOwner objsdev
|
||||
//---------------------------------------------------------------------
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Data.Objects;
|
||||
|
||||
namespace System.Web.UI.WebControls
|
||||
{
|
||||
public class EntityDataSourceContextCreatedEventArgs : EventArgs
|
||||
{
|
||||
private readonly ObjectContext _context;
|
||||
internal EntityDataSourceContextCreatedEventArgs(ObjectContext context)
|
||||
{
|
||||
_context = context;
|
||||
}
|
||||
public ObjectContext Context
|
||||
{
|
||||
get { return _context; }
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,27 @@
|
||||
//---------------------------------------------------------------------
|
||||
// <copyright file="EntityDataSourceContextCreatingEventArgs.cs" company="Microsoft">
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// </copyright>
|
||||
//
|
||||
// @owner [....]
|
||||
// @backupOwner objsdev
|
||||
//---------------------------------------------------------------------
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Data.Objects;
|
||||
|
||||
namespace System.Web.UI.WebControls
|
||||
{
|
||||
public class EntityDataSourceContextCreatingEventArgs : EventArgs
|
||||
{
|
||||
private ObjectContext _context;
|
||||
internal EntityDataSourceContextCreatingEventArgs() { }
|
||||
public ObjectContext Context
|
||||
{
|
||||
get { return _context; }
|
||||
set { _context = value; }
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,32 @@
|
||||
//---------------------------------------------------------------------
|
||||
// <copyright file="EntityDataSourceContextDisposingEventArgs.cs" company="Microsoft">
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// </copyright>
|
||||
//
|
||||
// @owner [....]
|
||||
// @backupOwner objsdev
|
||||
//---------------------------------------------------------------------
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.ComponentModel;
|
||||
using System.Data.Objects;
|
||||
|
||||
namespace System.Web.UI.WebControls
|
||||
{
|
||||
public class EntityDataSourceContextDisposingEventArgs : CancelEventArgs
|
||||
{
|
||||
private readonly ObjectContext _context = null;
|
||||
|
||||
internal EntityDataSourceContextDisposingEventArgs(ObjectContext instance)
|
||||
{
|
||||
_context = instance;
|
||||
}
|
||||
|
||||
public ObjectContext Context
|
||||
{
|
||||
get { return _context; }
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,205 @@
|
||||
//---------------------------------------------------------------------
|
||||
// <copyright file="EntityDataSourceMemberPath.cs" company="Microsoft">
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// </copyright>
|
||||
//
|
||||
// @owner [....]
|
||||
// @backupOwner [....]
|
||||
//---------------------------------------------------------------------
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Data.EntityClient;
|
||||
using System.Data.Metadata.Edm;
|
||||
using System.Diagnostics;
|
||||
using System.Globalization;
|
||||
using System.Reflection;
|
||||
using System.Data.Common;
|
||||
using System.Data.Objects;
|
||||
|
||||
namespace System.Web.UI.WebControls
|
||||
{
|
||||
/// <summary>
|
||||
/// A glorified linked list. Describes a chain of properties from a primitive
|
||||
/// type to a root entity.
|
||||
/// </summary>
|
||||
class EntityDataSourceMemberPath
|
||||
{
|
||||
private readonly EdmProperty property;
|
||||
private readonly PropertyInfo propertyInfo;
|
||||
private readonly EntityDataSourceMemberPath parent;
|
||||
private readonly bool isLocallyInteresting;
|
||||
private readonly Type clrType;
|
||||
private readonly bool isKey;
|
||||
|
||||
internal EntityDataSourceMemberPath(MetadataWorkspace ocWorkspace, EntityDataSourceMemberPath parent, EdmProperty property, bool isLocallyInteresting)
|
||||
{
|
||||
EntityDataSourceUtil.CheckArgumentNull(ocWorkspace, "ocWorkspace");
|
||||
EntityDataSourceUtil.CheckArgumentNull(property, "property");
|
||||
|
||||
this.property = property;
|
||||
this.parent = parent;
|
||||
this.isLocallyInteresting = isLocallyInteresting;
|
||||
this.clrType = EntityDataSourceUtil.GetMemberClrType(ocWorkspace, property);
|
||||
this.isKey = IsPropertyAKey(property);
|
||||
|
||||
// retrieve PropertyInfo (with respect to parent CLR type)
|
||||
StructuralType parentType = property.DeclaringType;
|
||||
Type parentClrType = EntityDataSourceUtil.GetClrType(ocWorkspace, parentType);
|
||||
|
||||
this.propertyInfo = EntityDataSourceUtil.GetPropertyInfo(parentClrType, this.property.Name);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Describes the member path in the form 'property1.property2...'. Use to
|
||||
/// determine display name for nested properties in the EDSC.
|
||||
/// </summary>
|
||||
/// <returns>Description of the </returns>
|
||||
internal string GetDescription()
|
||||
{
|
||||
string prefix = null == this.parent ? string.Empty : this.parent.GetDescription() + ".";
|
||||
return prefix + this.property.Name;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether original values of this member should be preserved.
|
||||
/// </summary>
|
||||
internal bool IsInteresting
|
||||
{
|
||||
get
|
||||
{
|
||||
// a member path is interesting if anything along the path is interesting
|
||||
return this.isLocallyInteresting || (null != this.parent && this.parent.IsInteresting);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether this member represents a primary key value.
|
||||
/// </summary>
|
||||
internal bool IsKey
|
||||
{
|
||||
get { return this.isKey; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether this member can be assigned a value of null.
|
||||
/// </summary>
|
||||
internal bool IsNullable
|
||||
{
|
||||
get { return this.property.Nullable; }
|
||||
}
|
||||
|
||||
internal bool IsScalar
|
||||
{
|
||||
get { return EntityDataSourceUtil.IsScalar(this.property.TypeUsage.EdmType); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the CLR type of the last member in the path.
|
||||
/// </summary>
|
||||
internal Type ClrType
|
||||
{
|
||||
get { return this.clrType; }
|
||||
}
|
||||
|
||||
internal object GetValue(EntityDataSourceWrapper entity)
|
||||
{
|
||||
object parentObjectValue = GetParentObjectValue(entity, false /* initialize */);
|
||||
if (null == parentObjectValue)
|
||||
{
|
||||
// use convention that property of null is null
|
||||
return null;
|
||||
}
|
||||
else
|
||||
{
|
||||
// get this property
|
||||
object propertyValue = this.propertyInfo.GetValue(parentObjectValue, new object[] { });
|
||||
|
||||
return propertyValue;
|
||||
}
|
||||
}
|
||||
|
||||
internal void SetValue(EntityDataSourceWrapper entity, object value)
|
||||
{
|
||||
object parentObjectValue = GetParentObjectValue(entity, true /* initialize */);
|
||||
|
||||
// set property value on parent
|
||||
this.propertyInfo.SetValue(parentObjectValue, value, new object[] { });
|
||||
}
|
||||
|
||||
private object Initialize(EntityDataSourceWrapper entity)
|
||||
{
|
||||
// get parent's value
|
||||
object parentObjectValue = GetParentObjectValue(entity, true /* initialize */);
|
||||
|
||||
// construct type instance for this property
|
||||
object propertyValue = EntityDataSourceUtil.InitializeType(this.ClrType);
|
||||
|
||||
// set property
|
||||
this.propertyInfo.SetValue(parentObjectValue, propertyValue, new object[] { });
|
||||
|
||||
return propertyValue;
|
||||
}
|
||||
|
||||
private object GetParentObjectValue(EntityDataSourceWrapper entity, bool initialize)
|
||||
{
|
||||
// get parent's value
|
||||
object parentObjectValue;
|
||||
|
||||
if (null == this.parent)
|
||||
{
|
||||
// at the top level, the entity is the value
|
||||
parentObjectValue = entity.WrappedEntity;
|
||||
}
|
||||
else
|
||||
{
|
||||
parentObjectValue = this.parent.GetValue(entity);
|
||||
|
||||
if (null == parentObjectValue && initialize)
|
||||
{
|
||||
parentObjectValue = this.parent.Initialize(entity);
|
||||
}
|
||||
}
|
||||
|
||||
return parentObjectValue;
|
||||
}
|
||||
|
||||
internal string GetEntitySqlValue()
|
||||
{
|
||||
// it.[member1].[member2]...
|
||||
string prefix;
|
||||
|
||||
if (null != parent)
|
||||
{
|
||||
prefix = parent.GetEntitySqlValue();
|
||||
}
|
||||
else
|
||||
{
|
||||
prefix = EntityDataSourceUtil.EntitySqlElementAlias;
|
||||
}
|
||||
|
||||
string eSql = prefix + "." + EntityDataSourceUtil.QuoteEntitySqlIdentifier(this.property.Name);
|
||||
|
||||
return eSql;
|
||||
}
|
||||
|
||||
private bool IsPropertyAKey(EdmProperty property)
|
||||
{
|
||||
bool isKey = false;
|
||||
EntityType entityType = property.DeclaringType as EntityType;
|
||||
if (null != entityType)
|
||||
{
|
||||
isKey = entityType.KeyMembers.Contains(property);
|
||||
}
|
||||
return isKey;
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
string prefix = null == this.parent ? string.Empty : this.parent.ToString() + "->";
|
||||
return prefix + this.property.Name;
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,303 @@
|
||||
//---------------------------------------------------------------------
|
||||
// <copyright file="EntityDataSourceQueryBuilder.cs" company="Microsoft">
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// </copyright>
|
||||
//
|
||||
// @owner [....]
|
||||
// @backupOwner [....]
|
||||
//---------------------------------------------------------------------
|
||||
|
||||
namespace System.Web.UI.WebControls
|
||||
{
|
||||
using System.Collections;
|
||||
using System.ComponentModel;
|
||||
using System.Data.Common;
|
||||
using System.Data.Metadata.Edm;
|
||||
using System.Data.Objects;
|
||||
using System.Diagnostics;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
|
||||
internal abstract class EntityDataSourceQueryBuilder<T>
|
||||
{
|
||||
private readonly DataSourceSelectArguments _arguments;
|
||||
private readonly string _commandText;
|
||||
private readonly ObjectParameter[] _commandParameters;
|
||||
private readonly string _whereExpression;
|
||||
private readonly ObjectParameter[] _whereParameters;
|
||||
private readonly string _entitySetQueryExpression;
|
||||
private readonly OrderByBuilder _orderByBuilder;
|
||||
private string _includePaths;
|
||||
private TypeUsage _resultType;
|
||||
private Nullable<int> _count;
|
||||
|
||||
protected EntityDataSourceQueryBuilder(DataSourceSelectArguments arguments,
|
||||
string commandText, ObjectParameter[] commandParameters,
|
||||
string whereExpression, ObjectParameter[] whereParameters, string entitySetQueryExpression,
|
||||
string selectExpression, string groupByExpression, ObjectParameter[] selectParameters,
|
||||
OrderByBuilder orderByBuilder,
|
||||
string includePaths)
|
||||
{
|
||||
_arguments = arguments;
|
||||
_commandText = commandText;
|
||||
_commandParameters = commandParameters;
|
||||
_whereExpression = whereExpression;
|
||||
_whereParameters = whereParameters;
|
||||
_entitySetQueryExpression = entitySetQueryExpression;
|
||||
_orderByBuilder = orderByBuilder;
|
||||
_includePaths = includePaths;
|
||||
}
|
||||
|
||||
internal delegate EntityDataSourceQueryBuilder<T> Creator(DataSourceSelectArguments arguments,
|
||||
string commandText, ObjectParameter[] commandParameters,
|
||||
string whereExpression, ObjectParameter[] whereParameters, string entitySetQueryExpression,
|
||||
string selectExpression, string groupByExpression, ObjectParameter[] selectParameters,
|
||||
OrderByBuilder orderByBuilder,
|
||||
string includePaths);
|
||||
|
||||
internal TypeUsage ResultType
|
||||
{
|
||||
get
|
||||
{
|
||||
Debug.Assert(_resultType != null, "ResultType is only valid after Build()");
|
||||
return _resultType;
|
||||
}
|
||||
}
|
||||
internal int TotalCount
|
||||
{
|
||||
get
|
||||
{
|
||||
Debug.Assert(_count.HasValue, "Count is not valid until after Build. And only then if computeCount is true");
|
||||
return _count.Value;
|
||||
}
|
||||
}
|
||||
internal IEnumerable Execute(ObjectQuery<T> queryT)
|
||||
{
|
||||
return (IEnumerable)(((IListSource)(queryT)).GetList());
|
||||
}
|
||||
|
||||
internal ObjectQuery<T> BuildBasicQuery(ObjectContext context, bool computeCount)
|
||||
{
|
||||
ObjectQuery<T> queryT = QueryBuilderUtils.ConstructQuery<T>(context, _entitySetQueryExpression, _commandText, _commandParameters);
|
||||
queryT = ApplyWhere(queryT);
|
||||
queryT = ApplySelect(queryT); // Select and/or GroupBy application
|
||||
_resultType = queryT.GetResultType();
|
||||
return queryT;
|
||||
}
|
||||
|
||||
internal ObjectQuery<T> CompleteBuild(ObjectQuery<T> queryT, ObjectContext context, bool computeCount, bool wasExtended)
|
||||
{
|
||||
if (computeCount)
|
||||
{
|
||||
_count = queryT.Count();
|
||||
}
|
||||
|
||||
queryT = wasExtended ? ApplyQueryableOrderByAndPaging(queryT) : ApplyOrderByAndPaging(queryT);
|
||||
queryT = ApplyIncludePaths(queryT);
|
||||
|
||||
return queryT;
|
||||
}
|
||||
|
||||
private ObjectQuery<T> ApplyWhere(ObjectQuery<T> queryT)
|
||||
{
|
||||
if (!String.IsNullOrEmpty(_whereExpression))
|
||||
{
|
||||
queryT = queryT.Where(_whereExpression, _whereParameters);
|
||||
}
|
||||
return queryT;
|
||||
}
|
||||
|
||||
protected abstract ObjectQuery<T> ApplySelect(ObjectQuery<T> queryT);
|
||||
|
||||
internal ObjectQuery<T> ApplyOrderBy(ObjectQuery<T> queryT)
|
||||
{
|
||||
string orderByClause;
|
||||
ObjectParameter[] orderByParameters;
|
||||
// Apply all possible ordering except the sort expression, because it might only be valid after the query has been extended
|
||||
_orderByBuilder.Generate(_resultType, out orderByClause, out orderByParameters, false /*applySortExpression*/);
|
||||
|
||||
return String.IsNullOrEmpty(orderByClause) ? queryT : queryT.OrderBy(orderByClause, orderByParameters);
|
||||
}
|
||||
|
||||
private ObjectQuery<T> ApplyOrderByAndPaging(ObjectQuery<T> queryT)
|
||||
{
|
||||
// This re-applys the order-by as part of the skip
|
||||
string orderByClause;
|
||||
ObjectParameter[] orderByParameters;
|
||||
_orderByBuilder.Generate(_resultType, out orderByClause, out orderByParameters, true /*applySortExpression*/);
|
||||
bool paging = _arguments.MaximumRows > 0 && _arguments.StartRowIndex >= 0;
|
||||
var hasOrderByClause = !String.IsNullOrEmpty(orderByClause);
|
||||
|
||||
if (paging)
|
||||
{
|
||||
if (!hasOrderByClause)
|
||||
{
|
||||
throw new InvalidOperationException(Strings.EntityDataSourceQueryBuilder_PagingRequiresOrderBy);
|
||||
}
|
||||
queryT = queryT.Skip(orderByClause, _arguments.StartRowIndex.ToString(CultureInfo.InvariantCulture), orderByParameters).Top(_arguments.MaximumRows.ToString(CultureInfo.InvariantCulture), QueryBuilderUtils.EmptyObjectParameters);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (hasOrderByClause)
|
||||
{
|
||||
queryT = queryT.OrderBy(orderByClause, orderByParameters);
|
||||
}
|
||||
}
|
||||
|
||||
return queryT;
|
||||
}
|
||||
|
||||
private ObjectQuery<T> ApplyQueryableOrderByAndPaging(ObjectQuery<T> queryT)
|
||||
{
|
||||
queryT = _orderByBuilder.BuildQueryableOrderBy(queryT) as ObjectQuery<T>;
|
||||
bool paging = _arguments.MaximumRows > 0 && _arguments.StartRowIndex >= 0;
|
||||
if (paging)
|
||||
{
|
||||
queryT = queryT.Skip(_arguments.StartRowIndex).Take(_arguments.MaximumRows) as ObjectQuery<T>;
|
||||
}
|
||||
|
||||
return queryT;
|
||||
}
|
||||
|
||||
private ObjectQuery<T> ApplyIncludePaths(ObjectQuery<T> objectQuery)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(_includePaths))
|
||||
{
|
||||
foreach (string include in _includePaths.Split(','))
|
||||
{
|
||||
string trimmedInclude = include.Trim();
|
||||
if (!string.IsNullOrEmpty(trimmedInclude))
|
||||
{
|
||||
objectQuery = objectQuery.Include(trimmedInclude);
|
||||
}
|
||||
}
|
||||
}
|
||||
return objectQuery;
|
||||
}
|
||||
}
|
||||
|
||||
internal class EntityDataSourceObjectQueryBuilder<T> : EntityDataSourceQueryBuilder<T>
|
||||
{
|
||||
private EntityDataSourceObjectQueryBuilder(DataSourceSelectArguments arguments,
|
||||
string commandText, ObjectParameter[] commandParameters,
|
||||
string whereExpression, ObjectParameter[] whereParameters, string entitySetQueryExpression,
|
||||
string selectExpression, string groupByExpression, ObjectParameter[] selectParameters,
|
||||
OrderByBuilder orderByBuilder,
|
||||
string includePaths)
|
||||
: base(arguments,
|
||||
commandText, commandParameters,
|
||||
whereExpression, whereParameters, entitySetQueryExpression,
|
||||
selectExpression, groupByExpression, selectParameters,
|
||||
orderByBuilder,
|
||||
includePaths)
|
||||
{
|
||||
}
|
||||
|
||||
static internal EntityDataSourceQueryBuilder<T>.Creator GetCreator()
|
||||
{
|
||||
return Create;
|
||||
}
|
||||
|
||||
static internal EntityDataSourceQueryBuilder<T> Create(DataSourceSelectArguments arguments,
|
||||
string commandText, ObjectParameter[] commandParameters,
|
||||
string whereExpression, ObjectParameter[] whereParameters, string entitySetQueryExpression,
|
||||
string selectExpression, string groupByExpression, ObjectParameter[] selectParameters,
|
||||
OrderByBuilder orderByBuilder,
|
||||
string includePaths)
|
||||
{
|
||||
return new EntityDataSourceObjectQueryBuilder<T>(arguments,
|
||||
commandText, commandParameters,
|
||||
whereExpression, whereParameters, entitySetQueryExpression,
|
||||
selectExpression, groupByExpression, selectParameters,
|
||||
orderByBuilder,
|
||||
includePaths);
|
||||
}
|
||||
|
||||
protected override ObjectQuery<T> ApplySelect(ObjectQuery<T> queryT)
|
||||
{
|
||||
return queryT;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
internal class EntityDataSourceRecordQueryBuilder : EntityDataSourceQueryBuilder<DbDataRecord>
|
||||
{
|
||||
private readonly string _selectExpression;
|
||||
private readonly string _groupByExpression;
|
||||
private readonly ObjectParameter[] _selectParameters;
|
||||
|
||||
private EntityDataSourceRecordQueryBuilder(DataSourceSelectArguments arguments,
|
||||
string commandText, ObjectParameter[] commandParameters,
|
||||
string whereExpression, ObjectParameter[] whereParameters, string entitySetQueryExpression,
|
||||
string selectExpression, string groupByExpression, ObjectParameter[] selectParameters,
|
||||
OrderByBuilder orderByBuilder,
|
||||
string includePaths)
|
||||
: base(arguments,
|
||||
commandText, commandParameters,
|
||||
whereExpression, whereParameters, entitySetQueryExpression,
|
||||
selectExpression, groupByExpression, selectParameters,
|
||||
orderByBuilder,
|
||||
includePaths)
|
||||
{
|
||||
_selectExpression = selectExpression;
|
||||
_groupByExpression = groupByExpression;
|
||||
_selectParameters = selectParameters;
|
||||
}
|
||||
|
||||
static internal EntityDataSourceQueryBuilder<DbDataRecord> Create(DataSourceSelectArguments arguments,
|
||||
string commandText, ObjectParameter[] commandParameters,
|
||||
string whereExpression, ObjectParameter[] whereParameters, string entitySetQueryExpression,
|
||||
string selectExpression, string groupByExpression, ObjectParameter[] selectParameters,
|
||||
OrderByBuilder orderByBuilder,
|
||||
string includePaths)
|
||||
{
|
||||
return new EntityDataSourceRecordQueryBuilder(arguments,
|
||||
commandText, commandParameters,
|
||||
whereExpression, whereParameters, entitySetQueryExpression,
|
||||
selectExpression, groupByExpression, selectParameters,
|
||||
orderByBuilder,
|
||||
includePaths);
|
||||
}
|
||||
|
||||
protected override ObjectQuery<DbDataRecord> ApplySelect(ObjectQuery<DbDataRecord> queryT)
|
||||
{
|
||||
Debug.Assert(!String.IsNullOrEmpty(_selectExpression), "Select expression should not be of zero length.");
|
||||
|
||||
if (!string.IsNullOrEmpty(_groupByExpression))
|
||||
{
|
||||
queryT = queryT.GroupBy(_groupByExpression, _selectExpression, _selectParameters);
|
||||
}
|
||||
else
|
||||
{
|
||||
queryT = queryT.Select(_selectExpression, _selectParameters);
|
||||
}
|
||||
return queryT;
|
||||
}
|
||||
}
|
||||
|
||||
internal static class QueryBuilderUtils
|
||||
{
|
||||
internal static readonly ObjectParameter[] EmptyObjectParameters = new ObjectParameter[] { };
|
||||
|
||||
internal static ObjectQuery<T> ConstructQuery<T>(ObjectContext context,
|
||||
string entitySetQueryExpression,
|
||||
string commandText,
|
||||
ObjectParameter[] commandParameters)
|
||||
{
|
||||
string queryExpression;
|
||||
ObjectParameter[] queryParameters;
|
||||
if (!string.IsNullOrEmpty(commandText))
|
||||
{
|
||||
queryExpression = commandText;
|
||||
queryParameters = commandParameters;
|
||||
}
|
||||
else
|
||||
{
|
||||
queryExpression = entitySetQueryExpression;
|
||||
queryParameters = QueryBuilderUtils.EmptyObjectParameters;
|
||||
}
|
||||
|
||||
return context.CreateQuery<T>(queryExpression, queryParameters);
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,141 @@
|
||||
//---------------------------------------------------------------------
|
||||
// <copyright file="EntityDataSourceReferenceGroup.cs" company="Microsoft">
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// </copyright>
|
||||
//
|
||||
// @owner [....]
|
||||
// @backupOwner [....]
|
||||
//---------------------------------------------------------------------
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Data.EntityClient;
|
||||
using System.Data.Metadata.Edm;
|
||||
using System.Diagnostics;
|
||||
using System.Globalization;
|
||||
using System.Reflection;
|
||||
using System.ComponentModel;
|
||||
using System.Data.Common;
|
||||
using System.Data.Objects.DataClasses;
|
||||
using System.Data.Objects;
|
||||
using System.Data;
|
||||
using System.Runtime.CompilerServices;
|
||||
|
||||
namespace System.Web.UI.WebControls
|
||||
{
|
||||
/// <summary>
|
||||
/// Groups together reference columns pointing at the same association end.
|
||||
/// </summary>
|
||||
internal abstract class EntityDataSourceReferenceGroup
|
||||
{
|
||||
private readonly AssociationSetEnd end;
|
||||
|
||||
protected EntityDataSourceReferenceGroup(AssociationSetEnd end)
|
||||
{
|
||||
EntityDataSourceUtil.CheckArgumentNull(end, "end");
|
||||
|
||||
this.end = end;
|
||||
}
|
||||
|
||||
internal AssociationSetEnd End { get { return this.end; } }
|
||||
|
||||
[MethodImpl(MethodImplOptions.NoInlining | MethodImplOptions.NoOptimization)]
|
||||
internal static EntityDataSourceReferenceGroup Create(Type entityType, AssociationSetEnd end)
|
||||
{
|
||||
EntityDataSourceUtil.CheckArgumentNull(entityType, "entityType");
|
||||
|
||||
Type groupType = typeof(EntityDataSourceReferenceGroup<>).MakeGenericType(entityType);
|
||||
return (EntityDataSourceReferenceGroup)Activator.CreateInstance(groupType, new object[] { end });
|
||||
}
|
||||
|
||||
internal abstract void SetKeyValues(EntityDataSourceWrapper wrapper, Dictionary<string, object> newKeyValues);
|
||||
|
||||
internal abstract EntityKey GetEntityKey(EntityDataSourceWrapper entity);
|
||||
}
|
||||
|
||||
internal class EntityDataSourceReferenceGroup<T> : EntityDataSourceReferenceGroup
|
||||
where T : class
|
||||
{
|
||||
public EntityDataSourceReferenceGroup(AssociationSetEnd end)
|
||||
: base(end)
|
||||
{
|
||||
}
|
||||
|
||||
internal override void SetKeyValues(EntityDataSourceWrapper wrapper, Dictionary<string, object> newKeyValues)
|
||||
{
|
||||
EntityDataSourceUtil.CheckArgumentNull(wrapper, "wrapper");
|
||||
|
||||
EntityReference<T> reference = GetRelatedReference(wrapper);
|
||||
|
||||
EntityKey originalEntityKeys = reference.EntityKey;
|
||||
|
||||
|
||||
if (null != newKeyValues)
|
||||
{
|
||||
if(null != originalEntityKeys)
|
||||
{
|
||||
// mix the missing keys from the original values
|
||||
foreach (var originalEntityKey in originalEntityKeys.EntityKeyValues)
|
||||
{
|
||||
object newKeyValue;
|
||||
if (newKeyValues.TryGetValue(originalEntityKey.Key, out newKeyValue))
|
||||
{
|
||||
// if any part of the key is null, the EntityKey is null
|
||||
if (null == newKeyValue)
|
||||
{
|
||||
newKeyValues = null;
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// add the original value for this partial key since it is not saved in the viewstate
|
||||
newKeyValues.Add(originalEntityKey.Key, originalEntityKey.Value);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// what we have in the newKeyValues should be sufficient to set the key
|
||||
// but if any value is null, the whole key is null
|
||||
foreach (var newKey in newKeyValues)
|
||||
{
|
||||
if (null == newKey.Value)
|
||||
{
|
||||
newKeyValues = null;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (null == newKeyValues)
|
||||
{
|
||||
// if the entity key is a compound key, and if any partial key is null, then the entitykey is null
|
||||
reference.EntityKey = null;
|
||||
}
|
||||
else
|
||||
{
|
||||
reference.EntityKey = new EntityKey(EntityDataSourceUtil.GetQualifiedEntitySetName(End.EntitySet), (IEnumerable<KeyValuePair<string, object>>)newKeyValues);
|
||||
}
|
||||
}
|
||||
|
||||
internal override EntityKey GetEntityKey(EntityDataSourceWrapper entity)
|
||||
{
|
||||
EntityKey key = GetRelatedReference(entity).EntityKey;
|
||||
return key;
|
||||
}
|
||||
|
||||
private EntityReference<T> GetRelatedReference(EntityDataSourceWrapper entity)
|
||||
{
|
||||
RelationshipManager relationshipManager = entity.RelationshipManager;
|
||||
Debug.Assert(relationshipManager != null, "couldn't get a relationship manager");
|
||||
EntityReference<T> reference = relationshipManager.GetRelatedReference<T>(
|
||||
this.End.ParentAssociationSet.ElementType.FullName,
|
||||
this.End.CorrespondingAssociationEndMember.Name);
|
||||
return reference;
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,75 @@
|
||||
//---------------------------------------------------------------------
|
||||
// <copyright file="EntityDataSourceSelectedEventArgs.cs" company="Microsoft">
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// </copyright>
|
||||
//
|
||||
// @owner [....]
|
||||
// @backupOwner objsdev
|
||||
//---------------------------------------------------------------------
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Data.Objects;
|
||||
using System.Collections;
|
||||
|
||||
namespace System.Web.UI.WebControls
|
||||
{
|
||||
public class EntityDataSourceSelectedEventArgs : EventArgs
|
||||
{
|
||||
private readonly ObjectContext _context;
|
||||
private readonly Exception _exception = null;
|
||||
private bool _exceptionHandled = false;
|
||||
private readonly IEnumerable _results = null;
|
||||
private readonly int _totalRowCount = 0;
|
||||
private readonly DataSourceSelectArguments _selectArguments;
|
||||
|
||||
internal EntityDataSourceSelectedEventArgs(ObjectContext context,
|
||||
IEnumerable results,
|
||||
int totalRowCount,
|
||||
DataSourceSelectArguments selectArgs)
|
||||
{
|
||||
_context = context;
|
||||
_results = results;
|
||||
_totalRowCount = totalRowCount;
|
||||
_selectArguments = selectArgs;
|
||||
}
|
||||
|
||||
internal EntityDataSourceSelectedEventArgs(Exception exception)
|
||||
{
|
||||
_exception = exception;
|
||||
}
|
||||
|
||||
public Exception Exception
|
||||
{
|
||||
get { return _exception; }
|
||||
}
|
||||
|
||||
public bool ExceptionHandled
|
||||
{
|
||||
get { return _exceptionHandled; }
|
||||
set { _exceptionHandled = value; }
|
||||
}
|
||||
|
||||
public IEnumerable Results
|
||||
{
|
||||
get { return _results; }
|
||||
}
|
||||
|
||||
public ObjectContext Context
|
||||
{
|
||||
get { return _context; }
|
||||
}
|
||||
|
||||
public int TotalRowCount
|
||||
{
|
||||
get { return _totalRowCount; }
|
||||
}
|
||||
|
||||
public DataSourceSelectArguments SelectArguments
|
||||
{
|
||||
get { return _selectArguments; }
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,43 @@
|
||||
//---------------------------------------------------------------------
|
||||
// <copyright file="EntityDataSourceSelectingEventArgs.cs" company="Microsoft">
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// </copyright>
|
||||
//
|
||||
// @owner [....]
|
||||
// @backupOwner objsdev
|
||||
//---------------------------------------------------------------------
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Web.UI;
|
||||
using System.Web.UI.WebControls;
|
||||
using System.Data.Objects;
|
||||
using System.ComponentModel;
|
||||
using System.Data.Metadata.Edm;
|
||||
|
||||
namespace System.Web.UI.WebControls
|
||||
{
|
||||
public class EntityDataSourceSelectingEventArgs : System.ComponentModel.CancelEventArgs
|
||||
{
|
||||
private readonly EntityDataSource _dataSource;
|
||||
private readonly DataSourceSelectArguments _selectArguments;
|
||||
|
||||
internal EntityDataSourceSelectingEventArgs(EntityDataSource dataSource, DataSourceSelectArguments selectArgs)
|
||||
{
|
||||
_dataSource = dataSource;
|
||||
_selectArguments = selectArgs;
|
||||
}
|
||||
|
||||
public EntityDataSource DataSource
|
||||
{
|
||||
get { return _dataSource; }
|
||||
}
|
||||
|
||||
public DataSourceSelectArguments SelectArguments
|
||||
{
|
||||
get { return _selectArguments; }
|
||||
}
|
||||
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,137 @@
|
||||
//---------------------------------------------------------------------
|
||||
// <copyright file="EntityDataSourceValidationException.cs" company="Microsoft">
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// </copyright>
|
||||
//
|
||||
// @owner [....]
|
||||
// @backupOwner [....]
|
||||
//---------------------------------------------------------------------
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Runtime.Serialization;
|
||||
using System.Web.DynamicData;
|
||||
|
||||
namespace System.Web.UI.WebControls
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents errors that occur when validating properties of a dynamic data source.
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
[SuppressMessage("Microsoft.Design", "CA1032:ImplementStandardExceptionConstructors", Justification = "SerializeObjectState used instead")]
|
||||
public sealed class EntityDataSourceValidationException : Exception, IDynamicValidatorException
|
||||
{
|
||||
/// <summary>
|
||||
/// Exception state used to serialize/deserialize the exception in a safe manner.
|
||||
/// </summary>
|
||||
[NonSerialized]
|
||||
private EntityDataSourceValidationExceptionState _state;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="EntityDataSourceValidationException" /> class.
|
||||
/// </summary>
|
||||
public EntityDataSourceValidationException()
|
||||
: base()
|
||||
{
|
||||
InitializeExceptionState(null);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="EntityDataSourceValidationException" /> class.
|
||||
/// </summary>
|
||||
/// <param name="message">Exception message.</param>
|
||||
public EntityDataSourceValidationException(string message)
|
||||
: base(message)
|
||||
{
|
||||
InitializeExceptionState(null);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="EntityDataSourceValidationException" /> class.
|
||||
/// </summary>
|
||||
/// <param name="message">Exception message.</param>
|
||||
/// <param name="innerException">Inner exception.</param>
|
||||
public EntityDataSourceValidationException(string message, Exception innerException)
|
||||
: base(message, innerException)
|
||||
{
|
||||
InitializeExceptionState(null);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="EntityDataSourceValidationException" /> class.
|
||||
/// </summary>
|
||||
/// <param name="message">Exception message.</param>
|
||||
/// <param name="innerExceptions">Inner exceptions.</param>
|
||||
internal EntityDataSourceValidationException(string message, Dictionary<string, Exception> innerExceptions)
|
||||
: base(message)
|
||||
{
|
||||
InitializeExceptionState(innerExceptions);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes internal exception state.
|
||||
/// </summary>
|
||||
/// <param name="innerExceptions">Inner exceptions.</param>
|
||||
private void InitializeExceptionState(Dictionary<string, Exception> innerExceptions)
|
||||
{
|
||||
_state = new EntityDataSourceValidationExceptionState(innerExceptions);
|
||||
SubscribeToSerializeObjectState();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns inner exceptions.
|
||||
/// </summary>
|
||||
IDictionary<string, Exception> IDynamicValidatorException.InnerExceptions
|
||||
{
|
||||
get { return _state.InnerExceptions; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Subscribes the SerializeObjectState event.
|
||||
/// </summary>
|
||||
private void SubscribeToSerializeObjectState()
|
||||
{
|
||||
SerializeObjectState += (exception, eventArgs) => eventArgs.AddSerializedState(_state);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Holds the exception state that will be serialized when the exception is serialized.
|
||||
/// </summary>
|
||||
[Serializable]
|
||||
private class EntityDataSourceValidationExceptionState : ISafeSerializationData
|
||||
{
|
||||
/// <summary>
|
||||
/// Inner exceptions.
|
||||
/// </summary>
|
||||
private readonly Dictionary<string, Exception> _innerExceptions;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="EntityDataSourceValidationExceptionState"/> class.
|
||||
/// </summary>
|
||||
/// <param name="innerExceptions"></param>
|
||||
public EntityDataSourceValidationExceptionState(Dictionary<string, Exception> innerExceptions)
|
||||
{
|
||||
_innerExceptions = innerExceptions ?? new Dictionary<string, Exception>();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns inner exceptions.
|
||||
/// </summary>
|
||||
public Dictionary<string, Exception> InnerExceptions
|
||||
{
|
||||
get
|
||||
{
|
||||
return _innerExceptions;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Completes the deserialization.
|
||||
/// </summary>
|
||||
/// <param name="deserialized">The deserialized object.</param>
|
||||
public void CompleteDeserialization(object deserialized)
|
||||
{
|
||||
((EntityDataSourceValidationException)deserialized)._state = this;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,182 @@
|
||||
//---------------------------------------------------------------------
|
||||
// <copyright file="EntityDataSourceViewSchema.cs" company="Microsoft">
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// </copyright>
|
||||
//
|
||||
// @owner [....]
|
||||
// @backupOwner [....]
|
||||
//---------------------------------------------------------------------
|
||||
|
||||
namespace System.Web.UI.WebControls
|
||||
{
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Data;
|
||||
using System.Data.Metadata.Edm;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
|
||||
internal class EntityDataSourceViewSchema : DataTable
|
||||
{
|
||||
internal EntityDataSourceViewSchema(EntityDataSourceWrapperCollection wrappers)
|
||||
{
|
||||
DataColumn column;
|
||||
List<DataColumn> keys = new List<DataColumn>();
|
||||
PropertyDescriptorCollection properties = wrappers.GetItemProperties(null);
|
||||
MetadataWorkspace workspace = wrappers.Context.MetadataWorkspace;
|
||||
foreach (EntityDataSourceWrapperPropertyDescriptor property in properties)
|
||||
{
|
||||
Type propertyType = property.PropertyType;
|
||||
column = ConstructColumn(property);
|
||||
|
||||
column.AllowDBNull = property.Column.IsNullable;
|
||||
|
||||
EntityDataSourcePropertyColumn propertyColumn = property.Column as EntityDataSourcePropertyColumn;
|
||||
if (null!= propertyColumn && propertyColumn.IsKey)
|
||||
{
|
||||
keys.Add(column);
|
||||
}
|
||||
Columns.Add(column);
|
||||
}
|
||||
this.PrimaryKey = keys.ToArray();
|
||||
}
|
||||
|
||||
internal EntityDataSourceViewSchema(ITypedList typedList)
|
||||
{
|
||||
PropertyDescriptorCollection properties = typedList.GetItemProperties(null);
|
||||
CreateColumnsFromPropDescs(properties, null);
|
||||
}
|
||||
|
||||
internal EntityDataSourceViewSchema(IEnumerable results)
|
||||
: this(results, null)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a view schema with a set of typed results and an optional set of keyName properties on those results
|
||||
/// </summary>
|
||||
internal EntityDataSourceViewSchema(IEnumerable results, string[] keyNames)
|
||||
{
|
||||
Type type = GetListItemType(results.GetType());
|
||||
PropertyInfo[] infos = type.GetProperties(BindingFlags.Public | BindingFlags.Instance);
|
||||
|
||||
PropertyDescriptorCollection properties = TypeDescriptor.GetProperties(type);
|
||||
CreateColumnsFromPropDescs(properties, keyNames);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a set of DataTable columns from a collection of property descriptors and an optional
|
||||
/// set of key names from metadata
|
||||
/// </summary>
|
||||
private void CreateColumnsFromPropDescs(PropertyDescriptorCollection properties, string[] keyNames)
|
||||
{
|
||||
List<DataColumn> keys = new List<DataColumn>();
|
||||
foreach (PropertyDescriptor property in properties)
|
||||
{
|
||||
System.ComponentModel.BrowsableAttribute attr =
|
||||
(System.ComponentModel.BrowsableAttribute)property.Attributes[typeof(System.ComponentModel.BrowsableAttribute)];
|
||||
if (attr.Browsable)
|
||||
{
|
||||
DataColumn column = ConstructColumn(property);
|
||||
// If there are keyNames, check if this column is one of the keys
|
||||
if (keyNames != null && keyNames.Contains(column.ColumnName))
|
||||
{
|
||||
keys.Add(column);
|
||||
}
|
||||
this.Columns.Add(column);
|
||||
}
|
||||
}
|
||||
if (keys.Count > 0)
|
||||
{
|
||||
this.PrimaryKey = keys.ToArray();
|
||||
}
|
||||
}
|
||||
|
||||
private static DataColumn ConstructColumn(PropertyDescriptor property)
|
||||
{
|
||||
DataColumn column = new DataColumn();
|
||||
column.ColumnName = property.Name;
|
||||
Type propertyType = property.PropertyType;
|
||||
|
||||
if (propertyType.IsGenericType && propertyType.GetGenericTypeDefinition() == typeof(Nullable<>))
|
||||
{
|
||||
Type[] typeArguments = propertyType.GetGenericArguments();
|
||||
Debug.Assert(typeArguments.Length == 1, "should only have one type argument from Nullable<> condition.");
|
||||
|
||||
column.DataType = typeArguments[0];
|
||||
column.AllowDBNull = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
column.DataType = propertyType;
|
||||
column.AllowDBNull = !propertyType.IsValueType;
|
||||
}
|
||||
column.ReadOnly = property.IsReadOnly;
|
||||
|
||||
column.Unique = false;
|
||||
column.AutoIncrement = false;
|
||||
column.MaxLength = -1;
|
||||
return column;
|
||||
}
|
||||
|
||||
// see System.Data.Objects.DataRecordObjectView.cs
|
||||
private static PropertyInfo GetTypedIndexer(Type type)
|
||||
{
|
||||
PropertyInfo indexer = null;
|
||||
|
||||
if (typeof(IList).IsAssignableFrom(type) ||
|
||||
typeof(ITypedList).IsAssignableFrom(type) ||
|
||||
typeof(IListSource).IsAssignableFrom(type))
|
||||
{
|
||||
System.Reflection.PropertyInfo[] props = type.GetProperties(BindingFlags.Public | BindingFlags.Instance);
|
||||
|
||||
for (int idx = 0; idx < props.Length; idx++)
|
||||
{
|
||||
if (props[idx].GetIndexParameters().Length > 0 && props[idx].PropertyType != typeof(object))
|
||||
{
|
||||
indexer = props[idx];
|
||||
//Prefer the standard indexer, if there is one
|
||||
if (indexer.Name == "Item")
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return indexer;
|
||||
}
|
||||
|
||||
// see System.Data.Objects.DataRecordObjectView.cs
|
||||
private static Type GetListItemType(Type type)
|
||||
{
|
||||
Type itemType;
|
||||
|
||||
if (typeof(Array).IsAssignableFrom(type))
|
||||
{
|
||||
itemType = type.GetElementType();
|
||||
}
|
||||
else
|
||||
{
|
||||
PropertyInfo typedIndexer = GetTypedIndexer(type);
|
||||
|
||||
if (typedIndexer != null)
|
||||
{
|
||||
itemType = typedIndexer.PropertyType;
|
||||
}
|
||||
else
|
||||
{
|
||||
itemType = type;
|
||||
}
|
||||
}
|
||||
|
||||
return itemType;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
@@ -0,0 +1,209 @@
|
||||
//---------------------------------------------------------------------
|
||||
// <copyright file="EntityDataSourceWrapper.cs" company="Microsoft">
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// </copyright>
|
||||
//
|
||||
// @owner [....]
|
||||
// @backupOwner [....]
|
||||
//---------------------------------------------------------------------
|
||||
using System;
|
||||
using System.Data;
|
||||
using System.Configuration;
|
||||
using System.ComponentModel;
|
||||
using System.Data.Common;
|
||||
using System.Data.Metadata.Edm;
|
||||
using System.Reflection;
|
||||
using System.Data.Objects;
|
||||
using System.Data.Objects.DataClasses;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Text;
|
||||
using System.Web.UI;
|
||||
|
||||
namespace System.Web.UI.WebControls
|
||||
{
|
||||
/// <summary>
|
||||
/// Wraps an entity displayed in the data source in an ICustomTypeDescriptor
|
||||
/// implementation that flattens complex types and exposes references.
|
||||
/// </summary>
|
||||
internal class EntityDataSourceWrapper : ICustomTypeDescriptor
|
||||
{
|
||||
private readonly EntityDataSourceWrapperCollection _collection;
|
||||
private readonly ObjectStateEntry _stateEntry;
|
||||
|
||||
internal EntityDataSourceWrapper(EntityDataSourceWrapperCollection collection, object trackedEntity)
|
||||
{
|
||||
EntityDataSourceUtil.CheckArgumentNull(collection, "collection");
|
||||
EntityDataSourceUtil.CheckArgumentNull(trackedEntity, "trackedEntity");
|
||||
|
||||
this._collection = collection;
|
||||
|
||||
// retrieve state entry
|
||||
if (!this._collection.Context.ObjectStateManager.TryGetObjectStateEntry(trackedEntity, out _stateEntry))
|
||||
{
|
||||
throw new ArgumentException(Strings.ComponentNotFromProperCollection, "trackedEntity");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets entity wrapped by this type descriptor.
|
||||
/// </summary>
|
||||
internal object WrappedEntity
|
||||
{
|
||||
get
|
||||
{
|
||||
return this._stateEntry.Entity;
|
||||
}
|
||||
}
|
||||
|
||||
internal RelationshipManager RelationshipManager
|
||||
{
|
||||
get
|
||||
{
|
||||
return this._stateEntry.RelationshipManager;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets collection containing this wrapper.
|
||||
/// </summary>
|
||||
internal EntityDataSourceWrapperCollection Collection
|
||||
{
|
||||
get { return this._collection; }
|
||||
}
|
||||
|
||||
#region ICustomTypeDescriptor Implementation
|
||||
System.ComponentModel.AttributeCollection System.ComponentModel.ICustomTypeDescriptor.GetAttributes() { return new System.ComponentModel.AttributeCollection(); }
|
||||
string ICustomTypeDescriptor.GetClassName() { return null; }
|
||||
string ICustomTypeDescriptor.GetComponentName() { return null; }
|
||||
TypeConverter ICustomTypeDescriptor.GetConverter() { return null; }
|
||||
EventDescriptor ICustomTypeDescriptor.GetDefaultEvent() { return null; }
|
||||
PropertyDescriptor ICustomTypeDescriptor.GetDefaultProperty() { return null; }
|
||||
object ICustomTypeDescriptor.GetEditor(Type editorBaseType) { return null; }
|
||||
EventDescriptorCollection ICustomTypeDescriptor.GetEvents() { return null; }
|
||||
EventDescriptorCollection ICustomTypeDescriptor.GetEvents(Attribute[] attributes) { return null; }
|
||||
|
||||
|
||||
public PropertyDescriptorCollection GetProperties()
|
||||
{
|
||||
return ((ITypedList)this._collection).GetItemProperties(null);
|
||||
}
|
||||
|
||||
PropertyDescriptorCollection ICustomTypeDescriptor.GetProperties(Attribute[] attributes)
|
||||
{
|
||||
return ((ICustomTypeDescriptor)this).GetProperties();
|
||||
}
|
||||
|
||||
object ICustomTypeDescriptor.GetPropertyOwner(PropertyDescriptor pd)
|
||||
{
|
||||
return this.WrappedEntity;
|
||||
}
|
||||
#endregion ICustomTypeDescriptor Implementation
|
||||
|
||||
/// <summary>
|
||||
/// Use this method to set the properties on the wrapped entity
|
||||
/// </summary>
|
||||
/// <param name="propertiesFromViewState"></param>
|
||||
/// <param name="wrapper"></param>
|
||||
/// <param name="overwriteSameValue"></param>
|
||||
internal void SetAllProperties(Dictionary<string, object> propertiesFromViewState, bool overwriteSameValue,
|
||||
ref Dictionary<string, Exception> propertySettingExceptionsCaught)
|
||||
{
|
||||
// We aggregate the reference descriptors rather than setting them directly
|
||||
// to account for compound keys (we need all components of the key to create
|
||||
// an EntityKey that can be set on the EntityReference)
|
||||
var referenceList = new List<KeyValuePair<EntityDataSourceReferenceKeyColumn, object>>();
|
||||
|
||||
foreach (EntityDataSourceWrapperPropertyDescriptor descriptor in _collection.AllPropertyDescriptors)
|
||||
{
|
||||
// figure out which display name to match for this descriptor
|
||||
string displayName = descriptor.Column.DisplayName;
|
||||
|
||||
// if we have a controlling column, use its display name instead
|
||||
if (descriptor.Column.ControllingColumn != null)
|
||||
{
|
||||
displayName = descriptor.Column.ControllingColumn.DisplayName;
|
||||
}
|
||||
|
||||
object value;
|
||||
if (propertiesFromViewState.TryGetValue(displayName, out value))
|
||||
{
|
||||
// get all changed ReferencePropertyDescriptor from ViewState
|
||||
EntityDataSourceReferenceKeyColumn referenceColumn = descriptor.Column as EntityDataSourceReferenceKeyColumn;
|
||||
|
||||
// convert the value as needed
|
||||
object adjustedValue = EntityDataSourceUtil.ConvertType(value, descriptor.PropertyType, descriptor.DisplayName);
|
||||
|
||||
if (null != referenceColumn)
|
||||
{
|
||||
referenceList.Add(new KeyValuePair<EntityDataSourceReferenceKeyColumn, object>(
|
||||
referenceColumn, adjustedValue));
|
||||
continue;
|
||||
}
|
||||
|
||||
if (overwriteSameValue || adjustedValue != descriptor.GetValue(this))
|
||||
{
|
||||
if (EntityDataSourceUtil.NullCanBeAssignedTo(descriptor.PropertyType) || null != adjustedValue)
|
||||
{
|
||||
try
|
||||
{
|
||||
descriptor.SetValue(this, adjustedValue);
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
// The property descriptor uses reflection to set the property. Therefore, the inner exception contains the actual message.
|
||||
Exception exceptionToThrow = e;
|
||||
if (e.InnerException != null)
|
||||
{
|
||||
exceptionToThrow = e.InnerException;
|
||||
}
|
||||
if (null == propertySettingExceptionsCaught)
|
||||
{
|
||||
propertySettingExceptionsCaught = new Dictionary<string, Exception>();
|
||||
}
|
||||
propertySettingExceptionsCaught.Add(descriptor.DisplayName, exceptionToThrow);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// aggregate setting for EntityKey
|
||||
SetEntityKeyProperties(referenceList, overwriteSameValue);
|
||||
}
|
||||
|
||||
private void SetEntityKeyProperties(
|
||||
List<KeyValuePair<EntityDataSourceReferenceKeyColumn, object>> referenceList, bool overwriteSameValue)
|
||||
{
|
||||
EntityDataSourceUtil.CheckArgumentNull(referenceList, "referenceList");
|
||||
|
||||
var groups = referenceList.GroupBy(r => r.Key.Group);
|
||||
|
||||
foreach (var group in groups)
|
||||
{
|
||||
Dictionary<string, object> partialKeys = new Dictionary<string, object>();
|
||||
|
||||
foreach (KeyValuePair<EntityDataSourceReferenceKeyColumn, object> reference in group)
|
||||
{
|
||||
// convert the value as needed
|
||||
EntityDataSourceReferenceKeyColumn column = reference.Key;
|
||||
object keyValue = reference.Value;
|
||||
|
||||
if (null == keyValue)
|
||||
{
|
||||
partialKeys = null;
|
||||
break;
|
||||
}
|
||||
|
||||
partialKeys.Add(column.KeyMember.Name, keyValue);
|
||||
}
|
||||
|
||||
// we only set the entitykey for once, although there might be more than one
|
||||
// properties descriptor associated with the same entitykey
|
||||
group.Key.SetKeyValues(this, partialKeys);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,180 @@
|
||||
//---------------------------------------------------------------------
|
||||
// <copyright file="EntityDataSourceWrapperCollection.cs" company="Microsoft">
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// </copyright>
|
||||
//
|
||||
// @owner [....]
|
||||
// @backupOwner [....]
|
||||
//---------------------------------------------------------------------
|
||||
using System;
|
||||
using System.Data;
|
||||
using System.Configuration;
|
||||
using System.Linq;
|
||||
using System.Web;
|
||||
using System.Web.Security;
|
||||
using System.Web.UI;
|
||||
using System.Web.UI.HtmlControls;
|
||||
using System.Web.UI.WebControls;
|
||||
using System.Web.UI.WebControls.WebParts;
|
||||
using System.Collections;
|
||||
using System.ComponentModel;
|
||||
using System.Collections.Generic;
|
||||
using System.Data.Metadata.Edm;
|
||||
using System.Data.Mapping;
|
||||
using System.Data.Objects;
|
||||
using System.Reflection;
|
||||
using System.Diagnostics;
|
||||
using System.Data.Common;
|
||||
using System.Data.Objects.DataClasses;
|
||||
using System.Globalization;
|
||||
using System.Data.EntityClient;
|
||||
using System.Collections.ObjectModel;
|
||||
|
||||
|
||||
namespace System.Web.UI.WebControls
|
||||
{
|
||||
/// <summary>
|
||||
/// Summary description for EntityDataSourceWrapperCollection
|
||||
/// </summary>
|
||||
internal class EntityDataSourceWrapperCollection : IEnumerable, ICollection, ITypedList
|
||||
{
|
||||
private readonly ObjectContext _context;
|
||||
private readonly List<EntityDataSourceWrapper> _wrapperList;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the property descriptors exposed to the user.
|
||||
/// </summary>
|
||||
private readonly PropertyDescriptorCollection _visiblePropertyDescriptors;
|
||||
|
||||
/// <summary>
|
||||
/// Gets all property descriptors.
|
||||
/// </summary>
|
||||
internal readonly ReadOnlyCollection<EntityDataSourceWrapperPropertyDescriptor> AllPropertyDescriptors;
|
||||
|
||||
private readonly bool _isReadOnly;
|
||||
private readonly Type _clrEntityType;
|
||||
|
||||
internal EntityDataSourceWrapperCollection(ObjectContext context, EntitySet entitySet, EntityType restrictedEntityType)
|
||||
{
|
||||
EntityDataSourceUtil.CheckArgumentNull(context, "context");
|
||||
EntityDataSourceUtil.CheckArgumentNull(entitySet, "entitySet");
|
||||
|
||||
_context = context;
|
||||
_wrapperList = new List<EntityDataSourceWrapper>();
|
||||
|
||||
// get handles on the relevant workspaces
|
||||
MetadataWorkspace csWorkspace = ((EntityConnection)context.Connection).GetMetadataWorkspace();
|
||||
MetadataWorkspace ocWorkspace = context.MetadataWorkspace;
|
||||
|
||||
// if no restricted type is given, we assume the entity set element type is exposed
|
||||
EntityType entityType = restrictedEntityType ?? entitySet.ElementType;
|
||||
_clrEntityType = EntityDataSourceUtil.GetClrType(ocWorkspace, entityType);
|
||||
|
||||
// if no restricted type is given and the set is polymorphic, make the collection readonly
|
||||
if (null == restrictedEntityType &&
|
||||
1 < EntityDataSourceUtil.GetTypeAndSubtypesOf(entityType, csWorkspace.GetItemCollection(DataSpace.CSpace), true).Count())
|
||||
{
|
||||
_isReadOnly = true;
|
||||
}
|
||||
|
||||
// gather the properties
|
||||
ReadOnlyCollection<EntityDataSourceColumn> columns = EntityDataSourceUtil.GetNamedColumns(csWorkspace, ocWorkspace, entitySet, entityType);
|
||||
List<PropertyDescriptor> visiblePropertyDescriptors = new List<PropertyDescriptor>(columns.Count);
|
||||
List<EntityDataSourceWrapperPropertyDescriptor> propertyDescriptors = new List<EntityDataSourceWrapperPropertyDescriptor>(columns.Count);
|
||||
foreach (EntityDataSourceColumn column in columns)
|
||||
{
|
||||
var descriptor = new EntityDataSourceWrapperPropertyDescriptor(this, column);
|
||||
propertyDescriptors.Add(descriptor);
|
||||
|
||||
// if the descriptor does not have a dependent, it is exposed to the user
|
||||
if (!descriptor.Column.IsHidden)
|
||||
{
|
||||
visiblePropertyDescriptors.Add(descriptor);
|
||||
}
|
||||
}
|
||||
|
||||
_visiblePropertyDescriptors = new PropertyDescriptorCollection(visiblePropertyDescriptors.ToArray(), true);
|
||||
AllPropertyDescriptors = propertyDescriptors.AsReadOnly();
|
||||
}
|
||||
|
||||
|
||||
internal EntityDataSourceWrapper AddWrappedEntity(object entity)
|
||||
{
|
||||
EntityDataSourceWrapper wrapper = new EntityDataSourceWrapper(this, entity);
|
||||
this._wrapperList.Add(wrapper);
|
||||
return wrapper;
|
||||
}
|
||||
|
||||
#region IEnumerable Implementation
|
||||
IEnumerator IEnumerable.GetEnumerator()
|
||||
{
|
||||
return this._wrapperList.GetEnumerator();
|
||||
}
|
||||
#endregion IEnumerable Implementation
|
||||
|
||||
#region ICollection Implementation
|
||||
public int Count
|
||||
{
|
||||
get { return this._wrapperList.Count; }
|
||||
}
|
||||
public void CopyTo(Array array, int index)
|
||||
{
|
||||
((ICollection)this._wrapperList).CopyTo(array, index);
|
||||
}
|
||||
public bool IsSynchronized
|
||||
{
|
||||
get { return false; }
|
||||
}
|
||||
public object SyncRoot
|
||||
{
|
||||
get { return null; }
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region ITypedList Implementation
|
||||
public PropertyDescriptorCollection GetItemProperties(PropertyDescriptor[] listAccessors)
|
||||
{
|
||||
if (null == listAccessors)
|
||||
{
|
||||
return this._visiblePropertyDescriptors ;
|
||||
}
|
||||
else
|
||||
{
|
||||
return null;// Implement this feature when we support traversing collections.
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
string ITypedList.GetListName(PropertyDescriptor[] listAccessors)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region Internal properties
|
||||
/// <summary>
|
||||
/// Gets CLR type or base type for entities exposed in this collection.
|
||||
/// </summary>
|
||||
internal Type ClrEntityType
|
||||
{
|
||||
get { return _clrEntityType; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether this configuration supports modifications.
|
||||
/// </summary>
|
||||
internal bool IsReadOnly
|
||||
{
|
||||
get { return _isReadOnly; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets object context tracking the contents of this collection.
|
||||
/// </summary>
|
||||
internal ObjectContext Context
|
||||
{
|
||||
get { return _context; }
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
@@ -0,0 +1,114 @@
|
||||
//---------------------------------------------------------------------
|
||||
// <copyright file="EntityDataSourceWrapperPropertyDescriptor.cs" company="Microsoft">
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// </copyright>
|
||||
//
|
||||
// @owner [....]
|
||||
// @backupOwner [....]
|
||||
//---------------------------------------------------------------------
|
||||
using System;
|
||||
using System.Data;
|
||||
using System.Configuration;
|
||||
using System.ComponentModel;
|
||||
using System.Data.Common;
|
||||
using System.Data.Metadata.Edm;
|
||||
using System.Reflection;
|
||||
using System.Data.Objects;
|
||||
using System.Data.Objects.DataClasses;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Text;
|
||||
|
||||
namespace System.Web.UI.WebControls
|
||||
{
|
||||
/// <summary>
|
||||
/// Wrapper property descriptor that handles access of nested members and
|
||||
/// entity reference keys.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This class essentially glues together a wrapper collection (roughly speaking
|
||||
/// the 'data' exposed by the control) and the column (which defines the metadata
|
||||
/// and behaviors for the current property).
|
||||
/// </remarks>
|
||||
internal sealed class EntityDataSourceWrapperPropertyDescriptor : PropertyDescriptor
|
||||
{
|
||||
private readonly EntityDataSourceWrapperCollection _collection;
|
||||
private readonly EntityDataSourceColumn _column;
|
||||
|
||||
internal EntityDataSourceWrapperPropertyDescriptor(EntityDataSourceWrapperCollection collection, EntityDataSourceColumn column)
|
||||
: base(EntityDataSourceUtil.CheckArgumentNull(column, "column").DisplayName, new Attribute[] { })
|
||||
{
|
||||
EntityDataSourceUtil.CheckArgumentNull(collection, "collection");
|
||||
|
||||
_collection = collection;
|
||||
_column = column;
|
||||
}
|
||||
|
||||
internal EntityDataSourceColumn Column
|
||||
{
|
||||
get { return _column; }
|
||||
}
|
||||
|
||||
public override Type ComponentType
|
||||
{
|
||||
get { return _collection.ClrEntityType; }
|
||||
}
|
||||
|
||||
public override bool IsReadOnly
|
||||
{
|
||||
get { return _collection.IsReadOnly || !_column.CanWrite; }
|
||||
}
|
||||
|
||||
public override Type PropertyType
|
||||
{
|
||||
get { return _column.ClrType; }
|
||||
}
|
||||
|
||||
public override bool CanResetValue(object component)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public override void ResetValue(object component)
|
||||
{
|
||||
throw new InvalidOperationException(Strings.ValueNotResettable(this.ComponentType.Name));
|
||||
}
|
||||
|
||||
public override object GetValue(object component)
|
||||
{
|
||||
return _column.GetValue(GetWrapper(component));
|
||||
}
|
||||
|
||||
public override void SetValue(object component, object value)
|
||||
{
|
||||
if (IsReadOnly)
|
||||
{
|
||||
throw new InvalidOperationException(Strings.SetValueNotSupported);
|
||||
}
|
||||
_column.SetValue(GetWrapper(component), value);
|
||||
}
|
||||
|
||||
public override bool ShouldSerializeValue(object component)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
private EntityDataSourceWrapper GetWrapper(object component)
|
||||
{
|
||||
// Validate that the component comes from the collection to which
|
||||
// this descriptor is bound. Elements of the collection are
|
||||
// non-null wrappers instances.
|
||||
EntityDataSourceUtil.CheckArgumentNull(component, "component");
|
||||
|
||||
EntityDataSourceWrapper wrapper = component as EntityDataSourceWrapper;
|
||||
if (null == wrapper || this._collection != wrapper.Collection)
|
||||
{
|
||||
throw new ArgumentException(Strings.ComponentNotFromProperCollection, "component");
|
||||
}
|
||||
|
||||
return wrapper;
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,266 @@
|
||||
//---------------------------------------------------------------------
|
||||
// <copyright file="OrderByBuilder.cs" company="Microsoft">
|
||||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// </copyright>
|
||||
//---------------------------------------------------------------------
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Specialized;
|
||||
using System.Data.Metadata.Edm;
|
||||
using System.Data.Objects;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Linq.Expressions;
|
||||
using System.Text;
|
||||
|
||||
namespace System.Web.UI.WebControls
|
||||
{
|
||||
internal class OrderByBuilder
|
||||
{
|
||||
private readonly string _argsSortExpression;
|
||||
private readonly EntityDataSourceWrapperCollection _wrapperCollection;
|
||||
private readonly string _orderBy;
|
||||
private readonly bool _autoGenerateOrderByClause;
|
||||
private readonly ParameterCollection _orderByParameters;
|
||||
private readonly EntityDataSource _owner;
|
||||
private readonly bool _generateDefaultOrderByClause;
|
||||
|
||||
internal OrderByBuilder(string argsSortExpression,
|
||||
EntityDataSourceWrapperCollection wrapperCollection,
|
||||
string orderBy,
|
||||
bool autoGenerateOrderByClause,
|
||||
ParameterCollection orderByParameters,
|
||||
bool generateDefaultOrderByClause,
|
||||
EntityDataSource owner)
|
||||
{
|
||||
_argsSortExpression = argsSortExpression;
|
||||
_wrapperCollection = wrapperCollection;
|
||||
_orderBy = orderBy;
|
||||
_autoGenerateOrderByClause = autoGenerateOrderByClause;
|
||||
_orderByParameters = orderByParameters;
|
||||
_owner = owner;
|
||||
_generateDefaultOrderByClause = generateDefaultOrderByClause;
|
||||
}
|
||||
|
||||
internal void Generate(TypeUsage tu, out string orderBy, out ObjectParameter[] orderByParameters, bool applySortExpression)
|
||||
{
|
||||
Debug.Assert(null != tu, "Type Usage cannot be null");
|
||||
GenerateOrderByClause(tu, out orderBy, out orderByParameters, applySortExpression);
|
||||
}
|
||||
|
||||
private void GenerateOrderByClause(TypeUsage tu, out string orderByClause, out ObjectParameter[] orderByObjectParameters, bool applySortExpression)
|
||||
{
|
||||
var orderByClauseBuilder = new StringBuilder();
|
||||
|
||||
if (applySortExpression)
|
||||
{
|
||||
// This sets the orderBy clause based on a clicked column header in the databound control.
|
||||
AppendOrderByKey(orderByClauseBuilder, _argsSortExpression, Strings.EntityDataSourceView_ColumnHeader, tu);
|
||||
}
|
||||
|
||||
// AutoGenerateOrderByClause is mutually exclusive with OrderBy.
|
||||
// Only one of the following two if statements will execute.
|
||||
if (_autoGenerateOrderByClause)
|
||||
{
|
||||
Debug.Assert(String.IsNullOrEmpty(_orderBy), "If AutoGenerateOrderByClause is true, then OrderBy cannot be set. This should have been caught by a runtime error check");
|
||||
IOrderedDictionary paramValues = _orderByParameters.GetValues(_owner.HttpContext, _owner);
|
||||
foreach (DictionaryEntry de in paramValues)
|
||||
{
|
||||
// Skip AutoGenerateOrderBy on expressions that have a null value.
|
||||
if (!string.IsNullOrEmpty((string)(de.Value)))
|
||||
{
|
||||
if (0 < orderByClauseBuilder.Length)
|
||||
{
|
||||
orderByClauseBuilder.Append(", ");
|
||||
}
|
||||
AppendOrderByKey(orderByClauseBuilder, (string)(de.Value), Strings.EntityDataSourceView_AutoGenerateOrderByParameters, tu);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Append the OrderBy expression, if it's nonzero length.
|
||||
if (!String.IsNullOrEmpty(_orderBy))
|
||||
{
|
||||
orderByObjectParameters = _owner.GetOrderByParameters();
|
||||
Debug.Assert(!_autoGenerateOrderByClause, "If OrderBy is set, AutoGenerateOrderBy must be false. This should have been caught by a runtime error check");
|
||||
if (0 < orderByClauseBuilder.Length)
|
||||
{
|
||||
orderByClauseBuilder.Append(", ");
|
||||
}
|
||||
orderByClauseBuilder.Append(_orderBy);
|
||||
}
|
||||
else
|
||||
{
|
||||
orderByObjectParameters = new ObjectParameter[] { };
|
||||
}
|
||||
|
||||
if (orderByClauseBuilder.Length==0 && _generateDefaultOrderByClause)
|
||||
{
|
||||
// This only occurs if there's no EntitySet, which means entities are not wrapped.
|
||||
orderByClauseBuilder.Append(GenerateDefaultOrderByFromTypeUsage(tu));
|
||||
}
|
||||
|
||||
orderByClause = orderByClauseBuilder.ToString();
|
||||
}
|
||||
|
||||
private void AppendOrderByKey(StringBuilder orderByClauseBuilder, string expression, string errorText, TypeUsage tu)
|
||||
{
|
||||
if (!String.IsNullOrEmpty(expression))
|
||||
{
|
||||
string[] statements = expression.Split(',');
|
||||
|
||||
string spacer = String.Empty;
|
||||
foreach (string statement in statements)
|
||||
{
|
||||
bool isAscending = true;
|
||||
string columnName = ParseStatement(statement.Trim(), out isAscending);
|
||||
|
||||
if (String.IsNullOrEmpty(columnName))
|
||||
{
|
||||
throw new ArgumentException(Strings.EntityDataSourceView_EmptyPropertyName);
|
||||
}
|
||||
|
||||
if (EntityDataSourceUtil.PropertyIsOnEntity(columnName, _wrapperCollection, null, tu))
|
||||
{
|
||||
orderByClauseBuilder.Append(spacer);
|
||||
orderByClauseBuilder.Append(EntityDataSourceUtil.GetEntitySqlValueForColumnName(columnName, _wrapperCollection));
|
||||
}
|
||||
else // pass the sort expression through verbatim.
|
||||
{
|
||||
if (!columnName.StartsWith("it.", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
columnName = "it." + columnName;
|
||||
}
|
||||
orderByClauseBuilder.Append(spacer + columnName);
|
||||
}
|
||||
|
||||
if (!isAscending)
|
||||
{
|
||||
orderByClauseBuilder.Append(c_esqlDescendingTail);
|
||||
}
|
||||
|
||||
spacer = ",";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private const string c_esqlAscendingTail = " ASC";
|
||||
private const string c_esqlDescendingTail = " DESC";
|
||||
private static readonly string[] ascendingTails = new string[] { c_esqlAscendingTail, " ascending" };
|
||||
private static readonly string[] descendingTails = new string[] { c_esqlDescendingTail, " descending" };
|
||||
|
||||
private static string ParseStatement(string statement, out bool isAscending)
|
||||
{
|
||||
foreach (string tail in descendingTails)
|
||||
{
|
||||
if (statement.EndsWith(tail, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
isAscending = false;
|
||||
return statement.Substring(0, statement.Length - tail.Length);
|
||||
}
|
||||
}
|
||||
|
||||
foreach (string tail in ascendingTails)
|
||||
{
|
||||
if (statement.EndsWith(tail, StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
isAscending = true;
|
||||
return statement.Substring(0, statement.Length - tail.Length);
|
||||
}
|
||||
}
|
||||
|
||||
isAscending = true;
|
||||
return statement;
|
||||
}
|
||||
|
||||
private static IQueryable ExpandQueryableOrderBy(IQueryable source, string[] statements)
|
||||
{
|
||||
var expression = source.Expression;
|
||||
var parameter = Expression.Parameter(source.ElementType, String.Empty);
|
||||
|
||||
for (int idx = 0; idx < statements.Length; idx++)
|
||||
{
|
||||
bool isAscending = true;
|
||||
// Try LINQ ascending/descending suffix
|
||||
string memberReference = ParseStatement(statements[idx], out isAscending);
|
||||
bool isFirstOrderBy = (idx == 0);
|
||||
|
||||
var methodName = (isFirstOrderBy ? "OrderBy" : "ThenBy") + (isAscending ? String.Empty : "Descending");
|
||||
|
||||
// Unravel nested property accesses
|
||||
var memberElements = memberReference.Split('.');
|
||||
Expression memberExpression = parameter;
|
||||
foreach (string memberElement in memberElements)
|
||||
{
|
||||
if (string.IsNullOrEmpty(memberElement))
|
||||
{
|
||||
throw new ArgumentException(Strings.EntityDataSourceView_EmptyPropertyName);
|
||||
}
|
||||
memberExpression = Expression.Property(memberExpression, memberElement.Trim());
|
||||
}
|
||||
|
||||
expression = Expression.Call(typeof(Queryable), methodName, new Type[] { source.ElementType, memberExpression.Type },
|
||||
new Expression[] { expression, Expression.Quote(DynamicExpression.Lambda(memberExpression, parameter)) });
|
||||
}
|
||||
|
||||
return source.Provider.CreateQuery(expression);
|
||||
}
|
||||
|
||||
internal IQueryable<TEntity> BuildQueryableOrderBy<TEntity>(IQueryable<TEntity> source)
|
||||
{
|
||||
IQueryable query = source;
|
||||
|
||||
// Process control's sort arguments if there are any
|
||||
if (_argsSortExpression != null & _argsSortExpression.Trim().Length > 0)
|
||||
{
|
||||
string[] statements = _argsSortExpression.Split(',');
|
||||
if (statements.Length > 0)
|
||||
{
|
||||
query = ExpandQueryableOrderBy(query, statements);
|
||||
}
|
||||
}
|
||||
|
||||
return query as IQueryable<TEntity>;
|
||||
}
|
||||
|
||||
private static string GenerateDefaultOrderByFromTypeUsage(TypeUsage tu)
|
||||
{
|
||||
StringBuilder orderByBuilder = new StringBuilder();
|
||||
ReadOnlyMetadataCollection<EdmProperty> propertyCollection;
|
||||
List<string> keyMemberNames = null;
|
||||
EntityType entityType = tu.EdmType as EntityType;
|
||||
|
||||
if (null != entityType)
|
||||
{
|
||||
ReadOnlyMetadataCollection<EdmMember> keyMembers;
|
||||
keyMembers = entityType.KeyMembers;
|
||||
keyMemberNames = new List<string>(entityType.KeyMembers.Count);
|
||||
propertyCollection = entityType.Properties;
|
||||
|
||||
foreach (EdmMember edmMember in keyMembers)
|
||||
{
|
||||
keyMemberNames.Add(edmMember.Name);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
return String.Empty;
|
||||
}
|
||||
|
||||
foreach (EdmProperty property in propertyCollection)
|
||||
{
|
||||
if (keyMemberNames.Contains(property.Name) && EntityDataSourceUtil.IsScalar(property.TypeUsage.EdmType))
|
||||
{
|
||||
if (0 < orderByBuilder.Length)
|
||||
{
|
||||
orderByBuilder.Append(", ");
|
||||
}
|
||||
orderByBuilder.Append(EntityDataSourceUtil.EntitySqlElementAlias);
|
||||
orderByBuilder.Append(".");
|
||||
orderByBuilder.Append(EntityDataSourceUtil.QuoteEntitySqlIdentifier(property.Name));
|
||||
}
|
||||
}
|
||||
return orderByBuilder.ToString();
|
||||
}
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user