I just started working with the new Entity Framework now that it has been released. One of the first tasks that I tackled was building an EF version of my LinqLength expression builder. Like my LinqLength expression builder, you can get a value for the MaxLength property from your schema:
<asp:TextBox ID="TextBox1" runat="server" Columns="50" MaxLength='<%$EntLength: Bellingham.Web.BellinghamEntities:BellinghamModel:Location:Name%>' />
I am still a little confused with all of relationships going on here and whether the model name is required to uniquely identify the entity given some database or conceptual models so I coded for both cases. If you only pass the expression builder three parameters, it will search across all models within the object context.
<asp:TextBox ID="TextBox1" runat="server" Columns="50" MaxLength='<%$EntLength: Bellingham.Web.BellinghamEntities:BelliLocation:Name%>' />
You will need to add this to your web.config file:
<expressionBuilders> <add expressionPrefix="EntLength" type="BinaryOcean.Web.Library.EntLengthExpressionBuilder" /></expressionBuilders>
Also, I haven't completed thorough perfomance testing but do save the Items Collection for the csdl between calls in the HttpContext. I played with different caching methods and I think this one is likely the best given the different trade offs. Asp.net caches the result for each Expression Builder call so it is only called once during the application life. (It is cached across different user threads within IIS.) Bottom line, this is very much a work in progress.
-Andy
>>>>
using System;using System.Collections.Generic;using System.Collections.ObjectModel;using System.CodeDom;using System.Data.Metadata.Edm;using System.Data.Objects;using System.Linq;using System.Web;using System.Web.Compilation;using System.Web.UI;
namespace BinaryOcean.Web.Library{ [ExpressionPrefix("EntLength")] public class EntLengthExpressionBuilder : ExpressionBuilder { public override CodeExpression GetCodeExpression(BoundPropertyEntry entry, object parsedData, ExpressionBuilderContext context) { string[] parameters = entry.Expression.Split(':');
CodePrimitiveExpression expression = null;
if (parameters.Count() == 3) expression = new CodePrimitiveExpression(GetFacetMaxLength(parameters[0], "", parameters[1], parameters[2]));
if (parameters.Count() == 4) expression = new CodePrimitiveExpression(GetFacetMaxLength(parameters[0], parameters[1], parameters[2], parameters[3]));
if (expression == null) ThrowException("Usage \"EntLength: EntityName[:ModelName]:TypeName:PropertyName\".");
return expression; }
private int GetFacetMaxLength(string contextName, string modelName, string entityName, string propertyName) { var entity = GetEntity(contextName, modelName, entityName);
var property = entity.Properties.SingleOrDefault(p => p.Name == propertyName); if (property == null) ThrowException(string.Format("Unable to find a single Property with Name \"{0}\"", propertyName));
var facet = property.TypeUsage.Facets.SingleOrDefault(f => f.Name == "MaxLength"); if (facet == null) ThrowException("Unable to find Facet with Name \"MaxLength\"");
if (!(facet.Value is int)) ThrowException(string.Format("Unable to derive value from Facet \"MaxLength\" with Value \"{0}\" on Property Name \"{1}\"", facet.Value, propertyName));
return (int)facet.Value; }
private EntityType GetEntity(string contextName, string modelName, string entityName) { var itemCollection = GetItemCollection(contextName);
EntityType entity; if (modelName.Length > 0) { entity = itemCollection.SingleOrDefault(i => i.NamespaceName == modelName && i.Name == entityName); if (entity == null) ThrowException(string.Format("Unable to find a single Entity with Model Name \"{0}\" and Name \"{1}\"", modelName, entityName)); } else { entity = itemCollection.SingleOrDefault(i => i.Name == entityName); if (entity == null) ThrowException(string.Format("Unable to find a single Entity with Name \"{0}\"", entityName)); } return entity; }
private ReadOnlyCollection<EntityType> GetItemCollection(string contextName) { var dictionary = GetDictionary();
if (dictionary.ContainsKey(contextName)) { return dictionary[contextName]; }
var context = (ObjectContext)Activator.CreateInstance(BuildManager.GetType(contextName, true)); var itemCollection = context.MetadataWorkspace.GetItemCollection(DataSpace.CSpace).GetItems<EntityType>(); dictionary.Add(contextName, itemCollection);
return itemCollection; }
private const string DictionaryCacheKey = "177808CC-5099-4972-8113-F61137DC1875"; // use a random guid as a key to insure uniqueness private Dictionary<string, ReadOnlyCollection<EntityType>> GetDictionary() { var dictionary = HttpContext.Current.Items[DictionaryCacheKey] as Dictionary<string, ReadOnlyCollection<EntityType>>;
if (dictionary == null) { dictionary = new Dictionary<string, ReadOnlyCollection<EntityType>>(); HttpContext.Current.Items[DictionaryCacheKey] = dictionary; }
return dictionary; }
private void ThrowException(string message) { throw new InvalidOperationException(string.Format("EntLengthExpressionBuilder: {0}", message)); } }}
Remember Me
a@href@title, strike
Powered by: newtelligence dasBlog 2.0.7226.0
Disclaimer The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.
© Copyright 2009, Andrew Robinson
E-mail