Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 8141907
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 6, 20262026-06-06T12:39:52+00:00 2026-06-06T12:39:52+00:00

I’ll start with some classes… The Domain Entity: public class Account { public int

  • 0

I’ll start with some classes…

The Domain Entity:

public class Account
{
    public int Id { get; set; }
    public double Balance { get; set; }
    public string CustomerName { get; set; }
}

The View Model:

public class AccountModel
{
    public int Id { get; set; }
    public double Bal { get; set; }
    public string Name { get; set; }
}

The Repository:

My repository has a method on it that takes an expression and returns a list, like this:

public interface IAccountRepository
{
    IEnumerable<Account> Query(Expression<Func<Account, bool>> expression);
} 

The Problem

My application generates an Expression<Func<AccountModel, bool>> in the UI. I need to somehow convert or map the EXPRESSION from AccountModel to Account so that I can use it in my Query method. I say “map” because, if you notice, my model and domain objects are similar, but don’t necessarily have the same property names.

How can this be done?

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-06T12:39:53+00:00Added an answer on June 6, 2026 at 12:39 pm

    This sounds like a job for AutoMapper. Automapper allows you to map one class to another at one point in time and use this mapping configuration later on.

    See the Projection page on the wiki for the kind of thing you are after.

    Update As you are using Entity Framework, here is an update for remapping your expression from using AccountModel to Account.

    In the CompositionRoot of your application, set up AutoMapper like so (ignore Code Contract statements if you do not use Code Contracts):

    var accountModelMap = Mapper.CreateMap<AccountModel, Account>();
    
    Contract.Assume(accountModelMap != null);
    accountModelMap.ForMember(account => account.Id, expression => expression.MapFrom(model => model.Id));
    accountModelMap.ForMember(account => account.Balance, expression => expression.MapFrom(model => model.Bal));
    accountModelMap.ForMember(account => account.CustomerName, expression => expression.MapFrom(model => model.Name));
    

    This configures how the two data types relate to eachother.

    Implement an ExpressionVisitor to use AutoMapper to rebind member access from one type to another.

    /// <summary>
    /// An <see cref="ExpressionVisitor"/> implementation which uses <see href="http://automapper.org">AutoMapper</see> to remap property access from elements of type <typeparamref name="TSource"/> to elements of type <typeparamref name="TDestination"/>.
    /// </summary>
    /// <typeparam name="TSource">The type of the source element.</typeparam>
    /// <typeparam name="TDestination">The type of the destination element.</typeparam>
    public class AutoMapVisitor<TSource, TDestination> : ExpressionVisitor
    {
        private readonly ParameterExpression _newParameter;
        private readonly TypeMap _typeMap = Mapper.FindTypeMapFor<TSource, TDestination>();
    
        /// <summary>
        /// Initialises a new instance of the <see cref="AutoMapVisitor{TSource, TDestination}"/> class.
        /// </summary>
        /// <param name="newParameter">The new <see cref="ParameterExpression"/> to access.</param>
        public AutoMapVisitor(ParameterExpression newParameter)
        {
            Contract.Requires(newParameter != null);
    
            _newParameter = newParameter;
            Contract.Assume(_typeMap != null);
        }
    
        [ContractInvariantMethod]
        [SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic", Justification = "Required for code contracts.")]
        private void ObjectInvariant()
        {
            Contract.Invariant(_typeMap != null);
            Contract.Invariant(_newParameter != null);
        }
    
        /// <summary>
        /// Visits the children of the <see cref="T:System.Linq.Expressions.MemberExpression"/>.
        /// </summary>
        /// <returns>
        /// The modified expression, if it or any subexpression was modified; otherwise, returns the original expression.
        /// </returns>
        /// <param name="node">The expression to visit.</param>
        protected override Expression VisitMember(MemberExpression node)
        {
            var propertyMaps = _typeMap.GetPropertyMaps();
            Contract.Assume(propertyMaps != null);
    
            // Find any mapping for this member
            var propertyMap = propertyMaps.SingleOrDefault(map => map.SourceMember == node.Member);
            if (propertyMap == null)
                return base.VisitMember(node);
    
            var destinationProperty = propertyMap.DestinationProperty;
    
            Contract.Assume(destinationProperty != null);
            var destinationMember = destinationProperty.MemberInfo;
    
            Contract.Assume(destinationMember != null);
    
            // Check the new member is a property too
            var property = destinationMember as PropertyInfo;
            if (property == null)
                return base.VisitMember(node);
    
            // Access the new property
            var newPropertyAccess = Expression.Property(_newParameter, property);
            return base.VisitMember(newPropertyAccess);
        }
    }
    

    Then implement an extension method to make this easier to use:

    /// <summary>
    /// A class which contains extension methods for <see cref="Expression"/> and <see cref="Expression{TDelegate}"/> instances.
    /// </summary>
    public static class ExpressionExtensions
    {
        /// <summary>
        /// Remaps all property access from type <typeparamref name="TSource"/> to <typeparamref name="TDestination"/> in <paramref name="expression"/>.
        /// </summary>
        /// <typeparam name="TSource">The type of the source element.</typeparam>
        /// <typeparam name="TDestination">The type of the destination element.</typeparam>
        /// <typeparam name="TResult">The type of the result from the lambda expression.</typeparam>
        /// <param name="expression">The <see cref="Expression{TDelegate}"/> to remap the property access in.</param>
        /// <returns>An <see cref="Expression{TDelegate}"/> equivalent to <paramref name="expression"/>, but applying to elements of type <typeparamref name="TDestination"/> instead of <typeparamref name="TSource"/>.</returns>
        public static Expression<Func<TDestination, TResult>> RemapForType<TSource, TDestination, TResult>(this Expression<Func<TSource, TResult>> expression)
        {
            Contract.Requires(expression != null);
            Contract.Ensures(Contract.Result<Expression<Func<TDestination, TResult>>>() != null);
    
            var newParameter = Expression.Parameter(typeof (TDestination));
    
            Contract.Assume(newParameter != null);
            var visitor = new AutoMapVisitor<TSource, TDestination>(newParameter);
            var remappedBody = visitor.Visit(expression.Body);
            if (remappedBody == null)
                throw new InvalidOperationException("Unable to remap expression");
    
            return Expression.Lambda<Func<TDestination, TResult>>(remappedBody, newParameter);
        }
    }
    

    This can subsequently be used like so (in an NUnit test):

    [TestFixture]
    public class RemappingTests
    {
        #region Setup/Teardown
        /// <summary>
        /// Sets up the variables before each test.
        /// </summary>
        [SetUp]
        public void Setup()
        {
            var accountModelMap = Mapper.CreateMap<AccountModel, Account>();
            Contract.Assume(accountModelMap != null);
            accountModelMap.ForMember(account => account.Id, expression => expression.MapFrom(model => model.Id));
            accountModelMap.ForMember(account => account.Balance, expression => expression.MapFrom(model => model.Bal));
            accountModelMap.ForMember(account => account.CustomerName, expression => expression.MapFrom(model => model.Name));
        }
    
        [TearDown]
        public void Teardown()
        {
            Mapper.Reset();
        }
        #endregion
    
        /// <summary>
        /// Checks that <see cref="ExpressionExtensions.RemapForType{TSource, TDestination, TResult}(Expression{Func{TSource, TResult}})"/> correctly remaps all property access for the new type.
        /// </summary>
        /// <param name="balance">The balance to use as the value for <see cref="Account.Balance"/>.</param>
        /// <returns>Whether the <see cref="Account.Balance"/> was greater than 50.</returns>
        [TestCase(0, Result = false)]
        [TestCase(80, Result = true)]
        public bool RemapperUsesPropertiesOfNewDataType(double balance)
        {
            Expression<Func<AccountModel, bool>> modelExpr = model => model.Bal > 50;
    
            var accountExpr = modelExpr.RemapForType<AccountModel, Account, bool>();
    
            var compiled = accountExpr.Compile();
            Contract.Assume(compiled != null);
    
            var hasBalance = compiled(new Account {Balance = balance});
    
            return hasBalance;
        }
    }
    

    In case that is too much code to find the exact call, here it is:

    Expression<Func<AccountModel, bool>> modelExpr = model => model.Bal > 50;
    var accountExpr = modelExpr.RemapForType<AccountModel, Account, bool>();
    
    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

link Im having trouble converting the html entites into html characters, (&# 8217;) i
I have just tried to save a simple *.rtf file with some websites and
For some reason, after submitting a string like this Jack’s Spindle from a text
Specifically, suppose I start with the string string =hello \'i am \' me And
I have a string like this: La Torre Eiffel paragonata all&#8217;Everest What PHP function
I am doing a simple coin flipping experiment for class that involves flipping a
I'm parsing an RSS feed that has an &#8217; in it. SimpleXML turns this
public static bool CheckLogin(string Username, string Password, bool AutoLogin) { bool LoginSuccessful; // Trim
I have some data like this: 1 2 3 4 5 9 2 6
That's pretty much it. I'm using Nokogiri to scrape a web page what has

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.