Mateo Velenik
Mateo Velenik

Reputation: 814

LINQ Select statement with EF - object initializer reuse assignment

I have a case in my application where I create selects over an IQueryable in this manner:

myContext.Data
    .Where(...)
    .OrderBy(...)
    .Select(p => new MyDataModel()
    {
        ...
        MyComplexProp = p.SomeProp.HasValue ? p.OtherProp.Name + " " + p.AnotherProp.Mark : p.EvenAnotherProp.Name,
        ...
    });

Now, the assignment to MyComplexProp is used on multiple places and I'd like to extract it to a single place so I can reuse it. Does anyone have an idea on how to achieve this?

I cannot use a static method because the IQueryable must not be executed in this phase.

Upvotes: 3

Views: 1106

Answers (2)

Jon Egerton
Jon Egerton

Reputation: 41569

Add a new constructor to MyDataModel to take the entity as an argument and do the logic:

public class MyDataModel
{
    public string MyComplexProp {get; set;}

    //Include a default constructor
    public MyDataModel()
    {
    }

    //Include a default constructor
    public MyDataModel(DataClass data)
    {
        MyComplexProp = data.SomeProp.HasValue ? data.OtherProp.Name + " " + data.AnotherProp.Mark : data.EvenAnotherProp.Name,
    }
}

Then your linq would simplify to:

myContext.Data
    .Where(...)
    .OrderBy(...)
    .AsEnumerable()
    .Select(p => new MyDataModel(p));

Note the use of the AsEnumerable(). This will mean that the constructor can execute in memory, but you will still have deferred execution of the query.

To acheive full DB side execution you'll need the logic converted to an expression. You're probably into creating an expression tree.

Upvotes: 1

Afshin Aghazadeh
Afshin Aghazadeh

Reputation: 547

I've already tested Extension Method for your question and It works. Here is the sample code:

namespace MyExtensionMethods
{
    //MyDataModel sample
    public class MyDataModel
    {
        public int? SomeProp { get; set; }
        public string OtherPropName { get; set; }
        public string AnotherPropMark { get; set; }
        public string EvenAnotherPropName { get; set; }
    }

    //The extension Method
    public static class ExtensionMethod
    {
        public static string ToMyComplexProp(this MyDataModel p)
        {
            return p.SomeProp.HasValue ? p.OtherPropName + " " + p.AnotherPropMark : p.EvenAnotherPropName;
        }
    }

    public class TestClass
    {
        MyDataModel myDataModel;
        public TestClass()
        {
            myDataModel = new MyDataModel();
            //This is the extension method and it's working
            myDataModel.ToMyComplexProp();
        }
    }
}

If you tried extension methods and it didn't work for you, the you declared it incorrectly. The soul purpose of extension method is for situations like this (Like how Linq is using it).

I suggest you to check MSDN Extension Method example to use it properly.

Upvotes: 0

Related Questions