I'm trying to perform a simple query in Entity Framework.
I have a list of funky things
List<FunkyThing> funkyThings;
Which has 1-5 unique FunkyThing
's in it.
FunkyThing
{
string FunkyThingUniqueCustomerCode{get;set}
string UsefullInfoRegardFunkyThings{get;set}
}
I'm trying to do a join onto the funky things table in my database.
The table looks something along the lines of:
FunkyThingsTable
int ID
string UniqueCustomerCode
string colour
string usefulInfoOfGreatValue
decimal cost
Now as it so happens there's approximately 300,000 funky things in this table.
What I was hoping to do is join my list on to my table to get the usefulInfoOfGreatValue element out. As follows:
var listOfFunkyThingsUsefulInfoQuery = from funkyThing in funkyThings
join
funkyThingDBEntity in unitOfWork.FunkyThingsRepository.Get()
on funkyThing.FunkyThingUniqueCustomerCode equals funkyThingDBEntity .UniqueCustomerCode
select new
{
uniqueCode= funkyThingDBEntity .UniqueCustomerCode,
usefulInfoOfGreatValue= funkyThingDBEntity .usefulInfoOfGreatValue
};
Unfortunately the query takes about 5 seconds to run -even with just one item in the list. What am I doing wrong?
A few quick notes. I'm using the unit of work pattern as described here: http://www.asp.net/mvc/tutorials/getting-started-with-ef-using-mvc/implementing-the-repository-and-unit-of-work-patterns-in-an-asp-net-mvc-application
The customers for long technical reasons don't have the integer ID, only a string customer code - hence this comparison.
Additional Notes: As per the unit of work article the unitOfWork.FunkyThingsRepository.Get() returns an IEnumerable:
public virtual IEnumerable<TEntity> Get
I've just tried re-working so use lambda as follows:
var listOfFunkyThingsUsefulInfoQuery = unitOfWork.FunkyThingsRepository.Get().Join (funkyThings, funkyThingDBEntity=>funkyThingDBEntity.UniqueCustomerCode, funkyThings=>funkyThings.FunkyThingUniqueCustomerCode ,(funkyThings,funkyThingDBEntity)=>new {uniqueCode= funkyThingDBEntity .UniqueCustomerCode, usefulInfoOfGreatValue=funkyThingDBEntity .usefulInfoOfGreatValue}) ;
However sadly this takes the same amount of time
Your query will cause all 300,000 rows be retrieved from the database to memory and perform the join there. Looking at your query, all you're trying to do is extract UsefulInfoOfGreatValue
associated with the items in funkyThings
based on UniqueCustomerCode
.
In the article, the Get()
method has a filter parameter that defaults to null. You can set this filter to make your query much faster (ie only get the rows you need)
Try this
var funkyThingsCustomerCodes = funkyThings.Select(x => x.FunkyThingUniqueCustomerCode).ToList();
var listOfFunkyThingsUsefulInfoQuery =
from funkyThing in unitOfWork.FunkyThingsRepository.Get(e => funkyThingsCustomerCodes.Contains(e.UniqueCustomerCode))
select new {
UniqueCode = funkyThing.UniqueCustomerCode,
UsefulInfoOfGreatValue = funkyThing.UsefulInfoOfGreatValue
};
Also if you create an index on UniqueCustomerCode
column in your table the above query will be even much faster.
try to use eager loading, and use include statement. It will be little faster. Please go through below links, it might help you.
http://msdn.microsoft.com/en-us/data/jj574232.aspx http://blogs.msdn.com/b/adonet/archive/2008/10/07/migrating-from-linq-to-sql-to-entity-framework-eager-loading.aspx
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.