Author Archives: admin

Maintaining the Identity of an Object Graph

Hands up if you have ever built a highly interactive WPF application! I feel your pain. ๐Ÿ™‚
Typically, in Banking the traders want to have all relevant information required for their day-to-day business compactly presented in very few or only one screen(s). This becomes challenging when the individual components are interactive, need to be up-to-date and can potentially be presented in multiple screens/tabs.
In one of my projects we faced the situation where out of a view model object graph messages had to be published to other view models in order to inform about certain events triggered by the user. The problem we had to solve was that the published messages had to be sent to all subscribes outside the view model object graph where the message originates from.
In the diagram below you see a set of object graph instances. The root object, PortfolioViewModel, sends and receives (RS) messages of type T and the DetailViewModel only receives (R) messages of the same type. The difficulty here is to make sure that the message is handled only by the subscribers that reside outside the object graph VM where the message originates from.

Typically, pub/sub messengers that come along with many MVVM frameworks do not provide information about the publisher. Even if, it would be difficult to find out whether the message has been sent by a VM within the same object graph.
An easy solution to solve that problem is to maintain a unique ID per object graph and send this information along with the published message. The subscriber needs to compare the ID of the origin against its own ID in order to know whether this message is relevant or not.
First we need a class representing the graph identity.

public class GraphIdentity : IGraphIdentity
{
    private Guid _id = Guid.NewGuid();
    public Guid Id => this._id;

    public bool IsItMe(IGraphIdentity id)
    {
        return this.Id == id.Id;
    }
}

Now this is the crucial part. We need to ensure that the GraphIdentity instance exists only once per object graph. If you are using a dependency injection framework (like Unity for example), it’s fairly easy to do.
The Unity container below uses for each ViewModel class the TransientLifetimeManager, meaning that a new instance is created each time when the Resolve function is being called.
And for the GraphIdentity the PerResolveLifetimeManager ensures that only one instance of that type exists within an object graph that is being constructed per single Resolve call.
That means, you can inject the same GraphIdentity instance at any place within a complex object graph.

Container = new UnityContainer();
Container.RegisterType<IPortfolioViewModel, PortfolioViewModel>();
Container.RegisterType<ITradeViewModel, TradeViewModel>();
Container.RegisterType<IDetailViewModel, DetailViewModel>();
Container.RegisterType<IGuidelineViewModel, GuidelineViewModel>();
Container.RegisterType<IGraphIdentity, GraphIdentity>(new PerResolveLifetimeManager());

That’s it already. Now let’s test it by creating three instances of the PortfolioViewModel and publish a message from objectGraph1 to objectGraph2 and objectGraph3 instances.

ApplicationConfiguration.Init();

var objectGraph1 = ApplicationConfiguration.Container.Resolve<IPortfolioViewModel>();
var objectGraph2 = ApplicationConfiguration.Container.Resolve<IPortfolioViewModel>();
var objectGraph3 = ApplicationConfiguration.Container.Resolve<IPortfolioViewModel>();

objectGraph1.SayHiToOther("Hi to object graph 2 and 3!");

As a result, we can see below that i) the same identity has been injected in the root and _detailVm instances per object graph and ii) the message published by the method “SayHiToOther” has been handled by objectGraph2 and objectGraph3 instances but not objectGraph1.

If you have time, you could extend your pub/sub messenger and centralize that logic so messages are sent only to the respective subscribes. This would reduce some lines of code in your VM as you don’t have to compare the GraphIdentity in your subscriber method anymore. ๐Ÿ˜‰

BIS Statistics F# Type Provider [alpha version]

The Bank for International Settlements (BIS) publishes statistics about the global financial system. The data is compiled in cooperation with central banks and other national authorities and provide information about financial stability. More information can be found on the BIS statistics website. Data exploration can be done either through the BIS Statistics Explorer, BIS Statistics Warehouse or by downloading the raw CSV formatted files. The last option is very interesting from an automation perspective, as it allows you to use your analysis tool of choice.
The following statistics can be downloaded from here:

  • Locational banking statistics
  • Consolidated banking statistics
  • Debt securities statistics
  • Credit to the non-financial sector
  • Debt service ratios for the private non-financial sector
  • Property prices: selected series
  • Property prices: long series
  • Effective exchange rate indices

As I’m exercising from time to time a bit with F#, I decided to write a Type Provider which i) extracts out of the CSV file the definition of the data ii) generates an abstraction layer which simplifies filtering on the file. The main advantages are:

  • Developer/research analyst analysis data through abstraction layer. No knowledge of CSV file parsing required.
  • The IDE provides syntax highlighting based on the definition extracted out of the CSV file. (The consumer does not need to know the dimension and codes by heart).
  • Compile time errors in case dimensions or codes which do not exist in the definition were used.
  • Simple but powerful way of filtering the data (observations).
  • One generic F# Type Provider for all above mentioned statistics.

The source code of the provider is available on GitHub and it’s currently in alpha state. There are some know issues but they don’t prevent you from browsing the “Property Prices”, “Locational Banking Statistics” and “Consolidated Banking Statistics” data as of the date of writing this blog post.
The following examples show how to utilize the BIS Type Provider.

Property Prices
I’ve downloaded the Property prices: long series CSV file as the structure of this data is very simple and perfect for this demo. Firstly (see code block below), the “PropertyPrice” type must be defined. By doing this, the BIS Type Provider analysis the CSV file and generates the PropertyPrice.ObservationFilter plus one type per dimension of the property price data. In this case the types “Frequency” and “Reference Area” were generated and each of them contains generated fields per dimension member.
As shown in the picture below, the definition of the data has been reflected in the code. With this, we have full IntelliSense support and compile-time checks!

Property Price - Reference Data dimension

Property Price – Reference Data dimension

It requires only 3-4 lines of code to filter out a certain observation out of the data. The last part of the code builds up a line chart for the data we were looking for. I’m using the FSharp.Charting for the visualization.

open System
open System.Linq
open System.Collections.Generic

open Bis
open FSharp.Charting

type PropertyPrice = Dataset<"C:/full_BIS_LONG_PP_csv.csv">

[<EntryPoint>]
let main argv = 
    
    // Create filter
    let filter = new PropertyPrice.ObservationFilter()

    // Define criteria
    filter.``Reference area`` <- [ PropertyPrice.``Reference area``.``CH:Switzerland`` ]

    // Apply filter and plot
    filter.Get()
        |> Seq.map (fun o -> 
                        o.values
                            |> Map.filter (fun k v -> v.IsSome)
                            |> Map.map (fun k v -> v.Value)
                            |> Map.toSeq
                            |> (fun x -> Chart.Line(x, Name = o.key)))
        |> Chart.Combine
        |> Chart.WithLegend(true, Title="Switzerland property prices")
        |> Chart.Show 

And this is the output of this code.

Property Prices - Switzerland

Property Prices – Switzerland

Consolidated Banking Statistics (CBS)
Let’s go one step further and analyse data of a much more complex dataset. The CBS file contains much more records and dimensions than the property prices. The following piece of code looks up a certain observation between Switzerland and Bahamas + Singapore and plots the outcome in a chart. Same as for the previous example, the CSV file was analysed by the BIS Type Provider and relevant types were generated. And again, we have full IntelliSense support as the properties on the “filter” and also the members under “Cbs” exist in code.

open System
open System.Linq
open System.Collections.Generic
open Bis

open FSharp.Charting

type Cbs = Dataset<"C:/full_BIS_CBS_csv.csv">

[<EntryPoint>]
let main argv = 
    
    let filter = new Cbs.ObservationFilter()

    filter.Measure                               <- [ Cbs.Measure.``S:Amounts outstanding / Stocks`` ]
    filter.``Reporting country``                 <- [ Cbs.``Reporting country``.``CH:Switzerland`` ]
    filter.``CBS bank type``                     <- [ Cbs.``CBS bank type``.``4R:Domestic banks(4B), excl. domestic positions`` ]
    filter.``CBS reporting basis``               <- [ Cbs.``CBS reporting basis``.``F:Immediate counterparty basis`` ]
    filter.``Balance sheet position``            <- [ Cbs.``Balance sheet position``.``I:International claims`` ]
    filter.``Type of instruments``               <- [ Cbs.``Type of instruments``.``A:All instruments`` ]
    filter.``Remaining maturity``                <- [ Cbs.``Remaining maturity``.``A:All maturities`` ]
    filter.``Currency type of booking location`` <- [ Cbs.``Currency type of booking location``.``TO1:All currencies``]
    filter.``Counterparty sector``               <- [ Cbs.``Counterparty sector``.``A:All sectors`` ]
    filter.``Counterparty country``              <- [ Cbs.``Counterparty country``.``BS:Bahamas``; Cbs.``Counterparty country``.``SG:Singapore`` ]  

    filter.Get()
        |> Seq.map (fun o -> 
                        o.values
                            |> Map.filter (fun k v -> v.IsSome)
                            |> Map.map (fun k v -> v.Value)
                            |> Map.toSeq
                            |> (fun x -> Chart.Line(x, Name = o.key)))
        |> Chart.Combine
        |> Chart.WithLegend(true, Title="Switzerland vis-ร -vis Bahamas and Singapore")
        |> Chart.Show 
CBS - Switzerland vis-a-vis Bahamas/Singapore

CBS – Switzerland vis-a-vis Bahamas/Singapore

The cbs.Filter() function returns a list of observations and their values for all periods. With F# you can easily slice out and aggregate data. In this code snippet we use the same filter as above and sum the values of 2015-Q1 across Bahamas and Singapore.

let sum = 
    filter.Get()
        |> Seq.map (fun o -> 
                        o.values
                        |> Map.filter (fun k v -> k = "2015-Q1" && v.IsSome)
                        |> Map.map (fun k v -> v.Value)
                        |> Map.toSeq
                        |> Seq.sumBy (fun (k,v) -> v))
    |> Seq.sum

I hope you like the BIS Type Provider. ๐Ÿ™‚ Contributions are welcome!

Exploring World Bank Data with F#

As part of my F# journey, I came to the idea to explore data provided by the World Bank. The follow F# code fetches Diesel prices in USD per liter.
These compontens have been used:

WorldBank Type Provider This provider enables the access to the World Banks data in a type-safe way. The beauty about F# type providers is that they take care of basically everything you need for the communcation to an external system. In my demo here, I didn’t not generate any service proxy representing World Banks API. But the IDE still provided me full IntelliSense support.
F# Charting Charting library for F#.

It took my a while to figure out how to write the code in a functional manner. But as you can see, the code is easy to read. First it loads Diesel prices by country (Switzerland, Norway, United States and Saudi Arabia), adds each identicator to the chart and plots it in the end.

open FSharp.Data
open FSharp.Charting

[<EntryPoint>]
let main argv = 

    let bank = WorldBankData.GetDataContext()
    let countries = 
        [| bank.Countries.Switzerland
           bank.Countries.Norway
           bank.Countries.``United States``
           bank.Countries.``Saudi Arabia`` |]

    [ for c in countries -> c.Indicators.``Pump price for diesel fuel (US$ per liter)`` ]
    |> List.map (fun i -> Chart.Line(i, i.Code))
    |> Chart.Combine
    |> Chart.WithLegend true
    |> Chart.Show

    0

The end result looks like this.
dieselprice

WPF Attached Dependency Property for Left Justified ComboBox

“Striving for perfection” is probably the slogan when one of our project owners is writing requirements for our project. Over the past months we had to implement various UI enhancements which are not supported in WPF by default. Thanks to the flexibility of WPF, we managed to implement a lot of them. I will probably start sharing them here on my blog.

Let’s start with a simple one. The following “LeftCursorJustifiedComboBox” Attached Dependency Property sets the cursor at the beginning of the selected text. By default, the WPF ComboBox marks the whole text and sets the cursor at the end as shown below in the left picture.
What we were looking for is presented in the right screen shot.

ComboBoxItemSelected LeftJustifiedComboBox

By attaching the following Dependency Property to a ComboBox, the control starts behaving as shown on the right picture.
The code is searching within the Visual Tree of the ComoboBox the TextBox element and sets the position of the cursor whenever the dropdown gets closed.

public static class LeftCursorJustifiedComboBox
{
    public static readonly DependencyProperty IsEnabledProperty = 
        DependencyProperty.RegisterAttached("IsEnabled", typeof(bool), typeof(ComboBox), new PropertyMetadata(OnChanged));

    public static bool GetIsEnabled(DependencyObject obj)
    {
        return (bool)obj.GetValue(IsEnabledProperty);
    }

    public static void SetIsEnabled(DependencyObject obj, bool value)
    {
        obj.SetValue(IsEnabledProperty, value);
    }
        
    private static void OnChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args)
    {
        SetIsEnabled(obj, (bool)args.NewValue);


        var box = (ComboBox)obj;

        box.DropDownClosed -= OnDropDownClosed;

        if (GetIsEnabled(obj))
        {
            box.DropDownClosed += OnDropDownClosed;
        }
    }

    private static void OnDropDownClosed(object sender, EventArgs e)
    {
        var textBox = ((ComboBox)sender).GetChild<TextBox>();
        textBox.CaretIndex = 0;
    }
}

public static class UIExtensions
{
    public static TChild GetChild<TChild>(this DependencyObject element) where TChild : DependencyObject
    {
        if (element is TChild)
        {
            return (TChild)element;
        }

        for (int x = 0; x < VisualTreeHelper.GetChildrenCount(element); x++)
        {
            var child = VisualTreeHelper.GetChild(element, x);
            var childElement = child.GetChild<TChild>();

            if (childElement != null)
            {
                return childElement;
            }
        }
        return null;
    }
}

But how do I know that the child element I’m looking for is of type TextBox? Thanks to the new Live Visual Tree feature in Visual Studio 2015 it’s pretty easy to figure out!
LiveVisualTree

F# Journey: Course 3 โ€“ Discriminated Unions

It has been a long time since my last post here.

One of my colleagues told me that the receptiveness of the human brain shrinks after reaching the 27 year. So it’s about time to learn F# before it’s too late! ๐Ÿ™‚

In this post I want to present an calculator example with discriminated unions. I think it’s an nice example which shows the power of the F# language.

As you can see in the code block below, I’ve defined a mathExpression descriminated union with the options “Add” and “Substract”. Both are accepting a tuple of two ints as a parameter.
The calculate pattern matching is used for the evaluation of the mathExpression.
At the bottom of the code block you see how the code can be utilized. With the current construction we don’t support nested operations.

type mathExpression =
        | Add       of int * int // tuple of two ints
        | Substract of int * int // tuple of two ints

    let calculate expression =
        match expression with
        | Add(left, right)       -> left + right // plus
        | Substract(left, right) -> left - right // minus

[<EntryPoint>]
let main argv = 
    let addition = Add(1, 1)
    let substraction = Substract(2, 1) 
    
    let addResult = calculate addition
    let subResult = calculate substraction

    printfn "addResult: %i" addResult
    printfn "subResult: %i" subResult
    0

Now let’s move one step further by enabling our calculator to evaluate nested operations. And we can do this by simply extending few pieces in our existing code. (See code block below)
I’ve added the “Constant” of type int to the mathExpression union. This represents a number within a formula.
I also changed the “Add” and “Substract” in order to accept a mathExpression and not only int values. This allows me to combine Add with Substract and vice versa.
In order to evaluate the expression we need to implement a recursive pattern matching and adjust “Add” and “Substract” cases in order to re-call the “calculate”.
With these few changes we enabled the calculator to deal with nested operations.

This is the beauty of F#. It would definitely take more effort to implement this in C#.

type mathExpression = 
        | Constant  of int                              // represents a number
        | Add       of mathExpression * mathExpression  // tuple of two mathExpressions
        | Substract of mathExpression * mathExpression  // tuple of two mathExpressions

    let rec calculate expression =
        match expression with
        | Constant(x)            -> x
        | Add(left, right)       -> calculate left + calculate right // plus
        | Substract(left, right) -> calculate left - calculate right // minus

[<EntryPoint>]
let main argv = 

    let addition = Add(Constant(1), Constant(1))
    let substraction = Substract(Constant(2), Constant(1)) 

    // NESTING!
    let complex = Add(Add(Add(Constant(1),Constant(1)), Substract(Add(Constant(1),Constant(2)),Constant(2))), Substract(Constant(4),Constant(1)))
    
    let addResult = calculate addition
    let subResult = calculate substraction
    let comResult = calculate complex

    printfn "addResult: %i" addResult
    printfn "subResult: %i" subResult
    printfn "comResult: %i" comResult

    0

My 2 Cents on Singleton

The implementation of the singleton pattern is pretty easy. However, despite the simplicity I see often that the pattern is being misused or implemented wrongly.

What I’ve seen so far:

  • The implementation is not thread-safe. (coding issue)
  • Tight coupling: The business code/logic accesses a static property of a class in order to utilize the singleton instance. (architectural/design issue)
  • Scope: Not all are aware of the fact that the singleton instance inside an web application is accessible within all user requests. (architectural/design issue)
  • Usage of singleton where it is not needed at all. (architectural/design issue)
  • Other bad things I finally managed to forget after excessive drinking. ๐Ÿ™‚

Overall, it is a good design pattern but I don’t agree with the recommended way of implementing it. I usually try to follow one of these approaches mentioned below.

1) Lazy<> class
If you are a .NET developer you can make use of the Lazy<> class. The constructor expects a Func<T> function in order to initialize the singleton instance. The implementation below is thread-safe. However, our code which uses this singleton class is still tightly coupled to SingletonExample which makes for example unit testing still difficult.

public class SingletonExample
{
    private static readonly Lazy<SingletonExample> _instance
        = new Lazy<SingletonExample>(() => new SingletonExample());
     
    private SingletonExample()
    { }
    
    public static SingletonExample Instance
    {
        get { return _instance.Value; }
    }
}

2) Lifetime management through dependency injection
This is definitely my favorite approach. But it requires a dependency injection framework. (I prefer Unity)
Almost every DI framework allows to control the lifetime of objects. The following example shows how to configure Unity in order to have just one instance of a specific class (in this case here “SingletonExample” class).
As you see here, there is no explicit Singleton implementation. The code below sets up a UnityContainer and registers the SingletonExample type with the ContainerControlledLifetimeManager. This lifetime manager ensures that only one instance of SingletonExample class exists within the UnityContainer.
There are many other lifetime managers out there. Therefore it is quite easy to change the behavior if required.
Also unit testing is now much simpler, since any instance of a class which impelments ISingletonExample can be injected through constructor/property injection.

...
var container = new UnityContainer();
container.RegisterType<ISingletonExample, SingletonExample>(new ContainerControlledLifetimeManager());
container.RegisterType<IMyLogic, MyLogic>();

var logic1 = container.Resolve<IMyLogic>();
var logic2 = container.Resolve<IMyLogic>();
... 

public interface ISingletonExample
{ }

public interface IMyLogic
{ }

public class SingletonExample : ISingletonExample
{ }

public class MyLogic : IMyLogic
{
    private readonly ISingletonExample _singleton;

    public MyLogic(ISingletonExample singleton)
    {
        this._singleton = singleton;
    }
}

IQueryable vs IEnumerable vs IHaveHeadache

Yes.. this ist just another blog post about IEnumerable<> and IQueryable<>. But the topic is quite important and I think it worth discussing about both approaches.

Recently I had a discussion with a software architect about the implementation of the repository pattern. The question was: Should the repository return IEnumerable<> or IQueryable<>?

So let’s do a rough comparison between both interfaces.

IEnumerable<> IQueryable<>
Used for in-memory data sources
Filtering in-memory
No lazy loading
No custom queries
Inherits from IEnumerable<>
Used for out of memory data soures (DB etc)
Filtering out of memory (SQL WHERE etc.)
Lazy loading supported
Custom query support

Back to the repository pattern. We were mainly discussion about two approaches. Writing classes like:

public class PersonRepository
{
    public IEnumerable<Person> GetByFirstName()
    { }

    public IEnumerable<Person> GetByAge()
    { }
}

Or like:

public class PersonRepository
{
    public IQueryable<Person> GetAll()
    { }
}

The first implementation uses IEnumerable<>. Each “Get” function is explicitly defined, which means the repository can be pretty big, but there will be less duplicate code.
And as a developer you get a good insight which functionality is provided by this repository.
The queries are executed either in the Repository class itself (by calling ToList() etc.) or by accessing the IEnumerable<> return object for the first time.
In the second repository has just one function which returns a IQueryable<> object. (There are no filter functions like “GetByAge” in the repository). The caller (business logic) is responsible for the filtering. Once the filter is defined, the business code can execute the filter by calling ToList(), First() etc. The whole IQueryable<> object including the filter criteria will be converted to SQL.

The advantages of the two approaches are:

IEnumerable<> IQueryable<>
It is easy to see which code is already implemented. This leads to less code duplication. Your filtering is there where it should be: In your business code
The queries are executed in the repository class (by calling ToList()) which allows you to handle the EF/SQL specific exceptions in the data access layer. Filter can be unit tested.
Query is executed when the data is needed.

The disadvantages are:

IEnumerable<> IQueryable<>
The filtering logic is hard to unit test. SQL/EF specific (technical) exceptions in you business code.
The repositories can get quite big. It “could” lead to code duplication. (Same filter logic written multiple times in different business logic)
You almost “force” to load the data. Changing the underlying LINQ provider could have impact on your business code. In worst case your new data source does not provide LINQ support.

There is one more interesting advantage with IQueryable<> which I never tested: Let’s say you query a huge amount of objects from the DB. When you do just a simple SELECT (without ordering etc) then the DB starts returning the rows even before the SELECT statement has finished. This is interesting because when you send the data to the client through WCF the serializer starts serializing the incoming DB rows and sends them to the client while the DB is continuously delivering the data.

In the end, I think the IQueryable<> approach is better. Even though it is maybe a bit more complex solution. Because the developers must understand the concept of IQueryable<> (making sure that queries are fired only once etc.) and it requires some discipline to prevent code duplication.

WCF Configuration for Large Data

In one of our projects we had to transfer large data from the server to the client WPF application. In the beginning we had some performance issues. Therefore we decided to do some comparisons between ASP.NET Web API, WCF (with and without protobuf-net).
The configuration:

ASP.NET Web API WCF (Protobuf) WCF
– Protobuf serializer
– IIS compression
– Protobuf serializer
– net.tcp protocol
– WCF 4.5 compression
– Standard serializer
– net.tcp protocol
– WCF 4.5 compression

After the first test with 100k objects we achieved good performance with WebAPI (protobuf) and WCF (protobuf). WCF with standard serializer was very slow. This mainly because the message transferred to the client was much bigger compared to WebAPI/WCF protobuf.

In the second round we compared only ASP.NET WebAPI (protobuf) with WCF (protobuf).
We did tests with 300k, 500k and 800k objects. For each test we called the WebAPI/WCF 5 times and took the avg. response time for the comparison.

While doing this we encountered some interesting issues:

WebAPI WebAPI was very unreliable. We had a lot peaks (“very” high response time). We had to call the WebAPI service 5-10 times to get a meaningful avg. time.
WCF WCF was very reliable. Regardless with how many objects we tested, we got more or less the same avg. response time after hitting the service 5 times.
Of course , the response time increased when we were testing with higher amount of objects. But the important part here is, that the time increased almost linear while WebAPI behavior was unpredictable.

Therefore we decided to use WCF (protobuf). The 2 main reasons are:
– Reliability (as described above)
– Much better performance when dealing with 500k or 800k objects.

C# Code Snippet for Unit Tests

After coding unit tests the whole day, I decided to create a nice Visual Studio snippet which helps me to write the test method quicker. I usually structure my unit tests like this:

public void Validate_ReturnsFalse_WhenStringIsTooLong()
{
	// Arrange
	var expectedResult = false;
	var watheverMock = new Mock<IWathever>();

	// Act
	var validator = new Validator(watheverMock.Object);
	var result = validator.Validate("test...");

	// Assert
	Assert.IsTrue(result == expectedResult, "Returned validation result: {0}. Expected validation result: {1}", result, expectedResult); 
} 

The method name is separated in three parts: “FunctionUnderTest”_”ExpectedResult”_”UnderWhichCondition”. And the unit test logic is build based on the AAA (Arrange,Act,Assert) pattern.
So my snippet does the typing work for you. (You can download the snippet here)
You can import the snippet file through the “Code Snippet Manager” under “Tools”.
Here an example how you can use it:
VS Unit Test

Entity Framework and Expression Queries

In my current project I had to generate a Entity Framework query based on some search criterias defined in a dictionary.
The structure of the dictionary was similar to this example here:

var searchCriteria = new Dictionary<string, List<string>>() 
{
    { "FirstName", new List<string> { "Darko", "NoName" } },
    { "LastName", new List<string> { "Micic", "Mรผller", "Obama" } }
};

The key contained the property/column name and the value containted a list of search criterias for this column. So first I wanted to build the query the type-safe way:

var query = model.People.AsQueryable();

if (searchCriteria.ContainsKey("FirstName"))
{
    var firstNames = searchCriteria["FirstName"];
    query = query.Where(x => firstNames.Contains(x.FirstName));
}

var result = query.ToList();

But I didn’t like that approach, because I need to handle each possible property on its own.
Therefore I decided to generate the query based on expressions. This is not a type-safe solution, but the approach leads to less code ๐Ÿ™‚

BinaryExpression condition = null;
var parameter = Expression.Parameter(typeof(Person), "p");

foreach (var criteria in searchCriteria)
{
    foreach (var comparisonValue in criteria.Value)
    {
        var property = Expression.Property(parameter, criteria.Key);
        var equalityCheck = Expression.Equal(property, Expression.Constant(comparisonValue));
        condition = condition == null ? equalityCheck : Expression.Or(condition, equalityCheck);
    }
}

The “condition” variable is an expression tree which contains “OR” combined comparison checks based on the search criteria. This expression can be used this way:

var query = model.People;
var predicate = Expression.Lambda<Func<Person, bool>>(condition, parameter);
var result = query.Where(predicate).ToList();

In debug mode we see how the comparison checks ar stitched together:
Ef Expression Condition
Entity Framework is able to convert this expression into a SQL “where” condition.

Nothing new… But I think this is not widely used.