Производительность LinqToSQL с проблемой «AsQueryable ()» - PullRequest
0 голосов
/ 09 февраля 2012

У меня есть уровень доступа к данным, который используется в качестве Linq-To-SQL в качестве ORM и используется шаблон репозитория.

Например,

public class OrderRepository : IRepository<DTO.Order>
{
        DTO.SampleDataContext _db = null;

        public OrderRepository()
        {
            _db = DataContextFactory.Create();
        }

        public OrderRepository(DTO.SampleDataContext db)
        {
            _db = db;
        }

        public IQueryable<DTO.Order> SelectAll()
        {
            var q = from o in _db.Orders
                    select o;

            return q.AsQueryable();
        }

И мой бизнес-уровень работает с результатомSelectAll() метод и запрос по его результатам.

В SQL Profiler Linq-to-SQL генерирует вложенный запрос, что-то вроде этого

select * from f1
(
    select * from Orders
) as f1
where f1.RecordDateTime > @p1

Есть ли проблемы с производительностью при таком подходе?

заранее спасибо

Ответы [ 2 ]

1 голос
/ 10 февраля 2012

Я бы порекомендовал вам не возвращаться как IQueryable. Потому что если вы планируете сделать что-то еще с вашим списком, что приведет к вызову базы данных. Например:

var test=db.YourTable.Select (u => u);
var ls= test.Where (a =>a.SomeColumn>9 );
var ls2= test.Where (t =>t.SomeColumn>4);

test.ToList();
ls.ToList();
ls2.ToList();

Когда три вызова toList сделаны, это приведет к 3 вызовам базы данных. Вызовы из базы данных в большинстве случаев дороже, чем зацикливание в памяти. В вашем случае я бы порекомендовал вам сделать что-то вроде этого:

public List<DTO.Order> SelectAll()
{
      var q = from o in _db.Orders
              select o;

       return q.ToList();
}
public List<DTO.Order> GetByRecordeDate(DateTime recordDateTime)
{
    var q = from o in _db.Orders
            where o.RecordDateTime>recordDateTime
            select o;

    return q.ToList();
}

Или, если вы действительно хотите сделать реализацию и использовать IQueryable, я бы порекомендовал вам сделать что-то вроде этого:

private IQueryable<DTO.Order> SelectAll()
{
    var q = from o in _db.Orders
            select o;

    return q;
}
private List<DTO.Order> GetAll()
{
    return SelectAll().ToList();
}
public List<DTO.Order> GetByRecordeDate(DateTime recordDateTime)
{
    var q = from o in SelectAll()
            where o.RecordDateTime>recordDateTime
            select o;

    return q.ToList();
}
1 голос
/ 10 февраля 2012

Если вы удалите вызов AsQueryable (), сгенерированный sql больше не будет вложенным запросом. Должно выглядеть так -

select * from Orders where f1.RecordDateTime > @p1
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...