Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Reuse Linq to SQL code with entityframework

I am currently doing some refactor on code that makes my application very slow. I am pretty far but i am still missing some pieces of the puzzle, i hope you can help me.

I like to reuse some Linq to SQL code inside of my project. This is my way of doing it at this moment:

public DomainAccount GetStandardUserAccount()
{
    return  this.DomainAccounts.Where(da => da.DomainAccountType == DomainAccountType.Standarduser).First() as DomainAccount;
}

var CurrentSituation = _context.Employees.ToList().Where(e => e.GetStandardUserAccount().Username.Contains("test")).ToList();

A small clarification: Every employee has multiple domain accounts where one always is a standarduser(DomainAccountType) domainaccount.

Because Linq can not convert an C# methode to an sqlstatement (Eventho its linq to sql code only) I have to convert the dbset to a list first so i can use the GetStandardUserAccount(). This code is is slow because of this whole dbset conversion. Is there a way i can reuse linq to sql code without turning it in an methode? I have read some threads and this is what I got untill now:

Func<Employee, DomainAccount> GetStandardDomainAccount = x => x.DomainAccounts.FirstOrDefault(d => d.DomainAccountType == DomainAccountType.Standarduser);
var TheGoal = _context.Employees.Where(e => e.GetStandardDomainAccount().Username.Contains("Something")).ToList();
like image 548
Pieter Avatar asked Sep 25 '26 02:09

Pieter


1 Answers

The answer to this question is a bit more complicated than it looks. In order to let linq execute C# code you need to make the function an expression so the in and output will be interperted not as code but as some sort of a meaning. The solution looks like this:

 private Expression<Func<TPeople, bool>> GetDefaultDomainAccount<TPeople>(Func<DomainAccount, bool> f) where TPeople : Person
        {
            return (a) => f(a.DomainAccounts.FirstOrDefault(d => d.DomainAccountType == DomainAccountType.Standarduser));
        }

Now the code can be called uppon like this:

    public IQueryable<TPeople> GetPeopleByUsername<TPeople>(string username) where TPeople : Person
    {
        GetPeople<TPeople>().Where(GetDefaultDomainAccount<TPeople>(d => d.Username == username));
        return people;
    }

instead of this:

        public IQueryable<TPeople> GetPeopleByUsername<TPeople>(string username) where TPeople : Person
    {
        username = username.ToUpper();
        var people = GetPeople<TPeople>()
            .Where(a => a.DomainAccounts.FirstOrDefault(d => d.DomainAccountType == DomainAccountType.Standarduser).Username.ToUpper().Contains(username));

        return people;
    }
like image 194
Pieter Avatar answered Sep 26 '26 16:09

Pieter



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!