RSS

Tag Archives: .Net

Repository and Unit of Work that is Fully Generic Part 3

So now for the last part the extensions to DBContext

using System;
using System.Data;
using System.Data.Entity;
using System.Data.Entity.Infrastructure;
using System.Data.Metadata.Edm;
using System.Linq;
using System.Reflection;

namespace MyCompany.Repo.Generic.Extensions
{
    ///
/// Code First extensions.
    ///
    public static class DbContextExtensions
    {
        ///
/// Adds an entity (if newly created) or update (if has non-default Id).
        ///
        ///
        ///The db context.
        ///The entity.
        ///
        ///
        /// Will not work for HasDatabaseGeneratedOption(DatabaseGeneratedOption.None).
        /// Will not work for composite keys.
        ///
        public static T AddOrUpdate(this DbContext context, T entity)
            where T : class
        {
            if (context == null) throw new ArgumentNullException("context");
            if (entity == null) throw new ArgumentNullException("entity");

            if (IsTransient(context, entity))
            {
                context.Set().Add(entity);
            }
            else
            {
                context.Set().Attach(entity);
                context.Entry(entity).State = EntityState.Modified;
            }
            return entity;
        }

        ///
/// Determines whether the specified entity is newly created (Id not specified).
        ///
        ///
        ///The context.
        ///The entity.
        ///
        ///   true if the specified entity is transient; otherwise, false.
        ///
        ///
        /// Will not work for HasDatabaseGeneratedOption(DatabaseGeneratedOption.None).
        /// Will not work for composite keys.
        ///
        public static bool IsTransient(this DbContext context, T entity)
            where T : class
        {
            if (context == null) throw new ArgumentNullException("context");
            if (entity == null) throw new ArgumentNullException("entity");

            var propertyInfo = FindPrimaryKeyProperty(context);
            var propertyType = propertyInfo.PropertyType;
            //what's the default value for the type?
            var transientValue = propertyType.IsValueType ?
                Activator.CreateInstance(propertyType) : null;
            //is the pk the same as the default value (int == 0, string == null ...)
            return Equals(propertyInfo.GetValue(entity, null), transientValue);
        }

        ///
/// Loads a stub entity (or actual entity if already loaded).
        ///
        ///
        ///The context.
        ///The id.
        ///
        ///
        /// Will not work for composite keys.
        ///
        public static T Load(this DbContext context, object id)
             where T : class
        {
            if (context == null) throw new ArgumentNullException("context");
            if (id == null) throw new ArgumentNullException("id");

            var property = FindPrimaryKeyProperty(context);
            //check to see if it's already loaded (slow if large numbers loaded)
            var entity = context.Set().Local
                .FirstOrDefault(x => id.Equals(property.GetValue(x, null)));
            if (entity == null)
            {
                //it's not loaded, just create a stub with only primary key set
                entity = CreateEntity(id, property);

                context.Set().Attach(entity);
            }
            return entity;
        }

        ///
/// Determines whether the specified entity is loaded from the database.
        ///
        ///
        ///The context.
        ///The id.
        ///
        ///   true if the specified entity is loaded; otherwise, false.
        ///
        ///
        /// Will not work for composite keys.
        ///
        public static bool IsLoaded(this DbContext context, object id)
            where T : class
        {
            if (context == null) throw new ArgumentNullException("context");
            if (id == null) throw new ArgumentNullException("id");

            var property = FindPrimaryKeyProperty(context);
            //check to see if it's already loaded (slow if large numbers loaded)
            var entity = context.Set().Local
                .FirstOrDefault(x => id.Equals(property.GetValue(x, null)));
            return entity != null;
        }

        ///
/// Marks the reference navigation properties unchanged.
        /// Use when adding a new entity whose references are known to be unchanged.
        ///
        ///
        ///The context.
        ///The entity.
        public static void MarkReferencesUnchanged(DbContext context, T entity)
            where T : class
        {
            var objectContext = ((IObjectContextAdapter)context).ObjectContext;
            var objectSet = objectContext.CreateObjectSet();
            var elementType = objectSet.EntitySet.ElementType;
            var navigationProperties = elementType.NavigationProperties;
            //the references
            var references = from navigationProperty in navigationProperties
                             let end = navigationProperty.ToEndMember
                             where end.RelationshipMultiplicity == RelationshipMultiplicity.ZeroOrOne ||
                             end.RelationshipMultiplicity == RelationshipMultiplicity.One
                             select navigationProperty.Name;
            //Note: We don't check Collections. EF wants to handle the object graph so we let it.

            var parentEntityState = context.Entry(entity).State;
            foreach (var navigationProperty in references)
            {
                //if it's modified but not loaded, don't need to touch it
                if (parentEntityState == EntityState.Modified &&
                    !context.Entry(entity).Reference(navigationProperty).IsLoaded)
                    continue;
                var propertyInfo = typeof(T).GetProperty(navigationProperty);
                var value = propertyInfo.GetValue(entity, null);
                context.Entry(value).State = EntityState.Unchanged;
            }
        }

        private static PropertyInfo FindPrimaryKeyProperty(IObjectContextAdapter context)
            where T : class
        {
            //find the primary key
            var objectContext = context.ObjectContext;
            //this will error if it's not a mapped entity
            var objectSet = objectContext.CreateObjectSet();
            var elementType = objectSet.EntitySet.ElementType;
            var pk = elementType.KeyMembers.First();
            //look it up on the entity
            var propertyInfo = typeof(T).GetProperty(pk.Name);
            return propertyInfo;
        }

        private static T CreateEntity(object id, PropertyInfo property)
            where T : class
        {
            // consider IoC here
            var entity = (T)Activator.CreateInstance(typeof(T));
            //set the value of the primary key (may error if wrong type)
            property.SetValue(entity, id, null);
            return entity;
        }
    }
}

  1. Create an Entity project
  2. Add EF 5 from nugget
  3. Add an ADO.Net Entity Data Model of your database
  4. Right click on the designer and click “Add Code Generation Item”
  5. If you do not have the EF 5.x DbContect Generator installed already click online templates select the EF 5.x DbContect Generator, name it appropriately, and click add.
  6. If they do not generat off the bat open the .tt and put in the correct .edmx file name and your db context and poco classes will generate
  7. Add the connection string into the consuming app and add your entity project and the generic repo to your consuming app. Then do something like this in you BLL J
            NPM_EXTEntities context = new NPM_EXTEntities();
            IUnitOfWork efu = new UoWFactory(context).getUoW();

            IGenericRepository<Application>; 
            applications = efu.GetRepository<Application>;
Advertisements
 
Leave a comment

Posted by on September 4, 2013 in C#, Entity Framework, Repository, SQL, Unit Of Work

 

Tags: , , , , , ,

Repository and Unit of Work that is Fully Generic Part 2

So now we continue with the Unit Of Work Factory and the EF specific Items along with Extensions to the DB Context

UoWFactory

using System;
using System.Collections.Generic;
using System.Linq;
using System.Data.Entity;

namespace MyCompany.Repo.Generic
{
    public class UoWFactory : IDisposable
    {
        #region Variables
        private readonly string _context;
        private readonly DbContext _DBcontext;
        #endregion

        #region Constructor(s)
        public UoWFactory(string context)
        {
            _context = context;
        }

        public UoWFactory(DbContext context)
        {
            _DBcontext = context;
        }
        #endregion

        #region Public Methods
        public IUnitOfWork GetUoW()
        {
            if (_DBcontext != null)
            {
                return new EFUnitOfWork( _DBcontext);
            }
            else
            {
                /*this will be the EL unit of work which needs to be fleshed out to 
                 * process the LINQ expressions for the IQueryable's and the like 
                 * this was beyond the scope of what I was asked to do for my project
                 * and will need to be finalized at a later time unless I have to convert from EF to EL
                 */                
               throw new NotImplementedException("EL Unit Of Work is currently unavailable");
            }
        }

        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }
        #endregion

        #region Protected and Private Methods
        protected virtual void Dispose(bool disposing)
        {
            if (disposing)
                if (_DBcontext != null)
                    _DBcontext.Dispose();
        }
        ~UoWFactory()
        {
            Dispose(false);
        }
        #endregion

    }
}

EFRepository

using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Data.Entity;
using System.Data;
using MyCompany.Repo.Generic.Extensions;

namespace MyCompany.Repo.Generic
{
    public class EFRepository<T> : BaseGenericRepository, IGenericRepository<T> where T : class
    {
        #region Variables
        private readonly DbContext _context;
        #endregion

        #region Constructor(s)
        public EFRepository(DbContext context)
        {
            _context = context;
        }
        #endregion

        #region Public Methods

        public override Type Type
        {
            get { return typeof(T); }
        }

        public T Value { get; set; }
 
        public IQueryable<T> Get
        {
            get { return _context.Set<T>(); }
        }
 
        public IQueryable<T> GetIncluding(params Expression<Func<T, object>>[] includeProperties)
        {
            IQueryable<T> query = _context.Set<T>();
            foreach (var includeProperty in includeProperties)
            {
                query = query.Include(includeProperty);
            }
            return query;
        }
 
        public T Find(object[] keyValues)
        {
            return _context.Set<T>().Find(keyValues);
        }
 
        public void Add(T entity)
        {
            _context.Set<T>().Add(entity);
        }
 
        public void Update(T entity)
        {
            var entry = _context.Entry(entity);
            if (entry.State == EntityState.Detached)
            {
                _context.Set<T>().Attach(entity);
                entry = _context.Entry(entity);
            }
            entry.State = EntityState.Modified;
        }
 
        public void AddOrUpdate(T entity)
        {
            //uses DbContextExtensions to check value of primary key
            _context.AddOrUpdate(entity);
        }
 
        public void Delete(object[] keyValues)
        {
            //uses DbContextExtensions to attach a stub (or the actual entity if loaded)
            var stub = _context.Load<T>(keyValues);
            _context.Set<T>().Remove(stub);
        }
        
        public void Dispose()
        {
            Dispose(true);
            GC.SuppressFinalize(this);
        }
        #endregion

        #region Protected and Private Methods
        protected virtual void Dispose(bool disposing)
        {
            if (disposing)
                if (_context != null)
                    _context.Dispose();
        }

        ~EFRepository()
        {
            Dispose(false);
        }
        #endregion

    }
}

EFUnitOfWork

using System;
using System.Collections.Generic;
using System.Linq;
using System.Data.Entity;
using System.Data;

namespace MyCompany.Repo.Generic
{
    public class EFUnitOfWork : IUnitOfWork
    {
        #region Variables
        private readonly DbContext context;
        private readonly Dictionary<Type, BaseGenericRepository> _dictionary;
        #endregion

        #region Constructor(s)
        public EFUnitOfWork(DbContext context)
        {
            this.context = context;
            this.context.ChangeTracker.DetectChanges();
            this.context.Configuration.AutoDetectChangesEnabled = true;
            _dictionary = new Dictionary<Type, BaseGenericRepository>();
        }
        #endregion

        #region Repository Collection Methods
        
            private void Put<T>(EFRepository<T> item) where T : class
            {
                _dictionary[typeof(T)] = item;
            }

            private EFRepository<T> Get<T>() where T : class
            {
                if (_dictionary.ContainsKey(typeof(T)))
                {
                    return _dictionary[typeof(T)] as EFRepository<T>;
                }
                else
                {                    
                    EFRepository<T> efr = new EFRepository<T>(context);
                    Put<T>(efr);
                    return efr;
                }                
            }

        #endregion

        #region Public Methods


        public IGenericRepository<T> GetRepository<T>() where T : class
        {            
            return Get<T>();
        }

        public void SaveChanges()
        {
            context.SaveChanges();
        }

        public void RollBack()
        {
            //detect all changes (probably not required if AutoDetectChanges is set to true)
            context.ChangeTracker.DetectChanges();

            //get all entries that are changed
            var entries = context.ChangeTracker.Entries().Where(e => e.State != EntityState.Unchanged).ToList();

            //try to discard changes on every entry
            foreach (var dbEntityEntry in entries)
            {
                var entity = dbEntityEntry.Entity;

                if (entity == null) continue;

                if (dbEntityEntry.State == EntityState.Added)
                {
                    //if entity is in Added state, remove it. (there will be problems with Set methods if entity is of proxy type, in that case you need entity base type
                    var set = context.Set(entity.GetType());
                    // now lets actually remove it
                    set.Remove(entity);
                }
                else if (dbEntityEntry.State == EntityState.Modified)
                {

                    context.Entry(dbEntityEntry.Entity).CurrentValues.SetValues(context.Entry(dbEntityEntry.Entity).OriginalValues);
                    //may also need to set back to unmodified -
                    //I'm unsure if EF will do this automatically
                    context.Entry(dbEntityEntry.Entity).State = EntityState.Unchanged;                    
                }
                else if (dbEntityEntry.State == EntityState.Deleted)
                    //entity is deleted... change its values back to default and set it to unmodified
                    context.Entry(dbEntityEntry).CurrentValues.SetValues(context.Entry(dbEntityEntry).OriginalValues);
                    dbEntityEntry.State = EntityState.Unchanged;
            }
        }

        public void Dispose()
        {
            context.Dispose();
        }

        #endregion

    }
}

 In part 3 we will show the extension methods for DBContext and go into useage.


 
Leave a comment

Posted by on September 4, 2013 in C#, Entity Framework, Repository, SQL, Unit Of Work

 

Tags: , , , , ,

Entity Framework Error 3004

Error 3004: Problem in mapping fragments starting at line <#>: No mapping specified for properties MyEntity.MyValue in Set MyEntities. An Entity with Key (PK) will not round-trip when: Entity is type [MyEntities.MyEntity]

This is a annoying error and the best thing to do is delete the offending table and regenerate the model. Not the greatest answer but when your pressed for time it is what it is.

 
Leave a comment

Posted by on January 2, 2013 in C#, Entity Framework, SQL

 

Tags: , ,

Use “LIKE()” Operation for Entity Frame Work (yes it is possible)

Alright so this is a tie in with the previous post but is still separate. I will get to that in the next post. So linq to entities was nice enough not to give us a true like operator like in linq to sql and if you use the linq to sql it throws a error and does not work against entities. So i needed a way and I found one but catch is it only works out of the box with mssql and for now we will stick with that. Sorry if you use oracle and the like suck to be there at the moment.

So here you go I have created a instance of a ObjectQuery and now I am adding on my filters for final execution and in this one I need to return a name with wild cards in place of spaces and special characters

vb .net

            Dim searchname As String = String.Format("%{0}%", replaceSpecialCharactersWith(TextBoxName.Text, "%"))
            entity = From client In entity.AsQueryable Where System.Data.Objects.SqlClient.SqlFunctions.PatIndex(searchname, client.Name) > 0 

C#

            string searchname = string.Format("%{0}%", replaceSpecialCharactersWith(TextBoxName.Text, "%"));
            entity = from client in entity.AsQueryablewhere System.Data.Objects.SqlClient.SqlFunctions.PatIndex(searchname, client.Name) > 0;

as you can see it uses the patindex function method from sql this along with deffered execution will allow you to do likes and then combine with the Or operator and you are good to go. Looking at the trace also it only tacked on a where calling the function so not much of a performance hit eithier. So using the code method below and this = automatic like on full name fields from a single textbox search :).

 
Leave a comment

Posted by on July 9, 2012 in C#, Entity Framework, SQL

 

Tags: , , ,

Replace Special And Non-ASCII Characters Without the Performance Hit of Regular Expressions

Alright so if your reading this you should know what Regular Expressions are, Now if you don’t go and use Google then come back :). Alright now that that is out of the way. So I needed to replace any special characters in a string before I passed it to another method to process it this case it was for a search function. Now here is the thing yes you can declare a reg-ex and then do a string.replace with the reg-ex but that caused a sever performance hit as it iterates through the whole expression for each character in the string. Alright now what about the people who use non-ASCII characters(yes some people do for some reason) with the code below it removes them also unlike reg-ex and by using the .net methods below you decrease the performance hit by over 2 fold.

For me this was a big deal because the data-source I was working with was huge. Now here is a basic truth you need to accept AND NOT DO WITH MY CODE before I give it to you, Strings in .net are Immutable if you don’t know what that is read the last part of the first sentence in this writeup. Alright…. if you are going to replace the special characters with quote quote DO NOT use “” as for each replacement it creates a separate string object until it leaves the for loop. Use String.Empty as the input parameter. So here you go in vb.net and C#….
VB.Net

    Public Shared Function replaceSpecialCharactersWith(text As String, replacement As String) As String
        Dim sb As New StringBuilder()
        Dim lastWasInvalid = False
        For Each c As Char In text
            If Char.IsLetterOrDigit(c) Then
                sb.Append(c)
                lastWasInvalid = False
            Else
                If Not lastWasInvalid Then
                    sb.Append(replacement)
                End If
                lastWasInvalid = True
            End If
        Next

        Return sb.ToString().ToLowerInvariant().Trim()

    End Function

C#

public static string replaceSpecialCharactersWith(string text, string replacement)
{
	StringBuilder strb = new StringBuilder();
	object lastWasInvalid = false;
	foreach (char c in text) 
	{
		if (char.IsLetterOrDigit(c)) 
		{
			strb.Append(c);
			lastWasInvalid = false;
		} 
		else 
		{
			if (!lastWasInvalid) 
			{
				strb.Append(replacement);
			}
			lastWasInvalid = true;
		}
	}

So for those who don’t understand it just in case, what it is doing is converting the string to a character array and looping through the character array and inserting the designated value for each if the if condition is met. If the character is valid it adds it to the string builder and moves to the next character. If the character is invalid it replaces it in the string builder with the specified replacement and marks the last character as invalid. The last part is so you don’t put 2 replacements side by side it just replaces once and goes till it finds another valid character :). Have fun and till next time don’t let your code have a meltdown.

 
Leave a comment

Posted by on July 9, 2012 in C#, Entity Framework

 

Tags: , , ,

Using Telerik RadAjaxPanel and RadAjaxLoading Panel

So as some of you know I am all about Telerik asp.net Ajax controls when you understand them they save you a great deal of time and can give you some cool features with just a little drag and drop. Add about  60 seconds of typing to set up the controls and bam. As we all know users are sometimes impatient we have gotten them used to instant everything these days on the web and sometimes that’s just not possible.
A few things are going to take a second or 2. This is definitely an issue when using ajax and server request event validation and you get an impatient user who just wants to keep working and not wait on the post back.

Enter RadAjaxPanel and RadLoadingPanel check out the following code snippet

<telerik:RadAjaxLoadingPanel ID="RadAjaxLoadingPanel1" runat="server">
	<div class="loading" style=" margin-top:50%; margin-bottom:50%; margin-left:auto; margin-right:auto;">

		<asp:Image ID="Image1" runat="server" ImageUrl="Img/loading44.gif" AlternateText="loading..."/>

	</div>
<telerik:RadAjaxLoadingPanel>
<telerik:RadAjaxPanel ID="RadAjaxPanel1" runat="server" LoadingPanelID="RadAjaxLoadingPanel1"
						EnableHistory="True" HorizontalAlign="NotSet">
<!-- Put your content here -->
<telerik:RadAjaxPanel>

in the code snippet above I achieve 3 main things instantly with the above code snippet
1. user cannot click on the controls after a post back begins until the post back ends. During that time the loading panel covers the entire RadAjaxPanel until its finished

2. I can display a custom (read Branded) loading gif and if it fails it just says loading.

3 it allows my user to know what is going on, stops them from messing with anything else in the panel, and also allows them to see when to proceed if i just disabled or overlayed the controls the user would become confused or think their browser/website was broken and in come the support tickets.

This takes all of 2 minutes and did i mention it provides instant ajax history without you having to create all the tedium that comes along with that all in 2 simple controls I will post an example site once I get home. Till then don’t let your code have a melt down.

 
Leave a comment

Posted by on March 13, 2012 in ASP.Net, C#

 

Tags: , , ,

How Setting Up Web Config Transformation Files can Save you Time and Avoid Deployment Mistakes.

So let’s be honest, even if no one ever noticed because we caught it before the damage was done, We have all deployed a site with the developement connection string still in place. This and things like it happen when you manually set up your web config. Well heres the answer to things like that —

http://msdn.microsoft.com/en-us/library/dd465318.aspx

So what is Web Configuration Transformation, for those who don’t want to click yet I will explain. Transformation is a addon item to your web config file that allows you to declare items to be replaced based on the compilation type you set in your build type drop box at the top of your VS(Visusal Studio) IDE. So if I build in Release mode then the Web.Release.Config transformation file kicks in and replaces the values I told it to, in most cases for me this deals with connection strings to databases and names/addresses for web services. This is handy because you can include it in the svn check out and everyone has it so no more pesky ooops I forgot to change my connections just do it once, maintain it, and bam you sir are good to go.

 
Leave a comment

Posted by on March 12, 2012 in ASP.Net, C#, C# for Beginners

 

Tags: , ,