Как спроектировать мой код службы / репозитория с Linq2Sql! - PullRequest
2 голосов
/ 23 февраля 2010

У меня проблема с созданием приложения.

У меня есть следующая структура с показом только важных аспектов.

namespace Domain
{
   public class Invoice
   {
     //properties
   }

public class InvoiceRepository
{
   public Linq2SqlContext context = new Linq2SqlContext();

   public IQueryable<Invoice> GetInvoices()
   {
              var query = from inv in _dbctx.Invoices orderby inv.invInvoiceDate descending select GetInvoice(inv) ;

            return query;

   }
}
public class InvoiceService()
{
   public InvoiceRepository _repository = new InvoiceRepositroy();
   public IQueryable<Invoice> GetInvoices()
   {
      return _repository.GetInvoices();
   }   

}
}

namespace MyApp
{
   public class UI
   {
      public InvoiceService _service =  new InvoiceService();
      public void FilterInvoices()
      {
            var query =
                   (
                     from i in _service.GetInvoices()
                     from s in _service.GetStatuses()
                     where i.ProjectID == _projectid &&
                           s.ID == i.Status
                     select new
                     {
                         InvoiceID = i.ID,
                         DocumentTotal = i.TotalDue.ToString(),
                         Created = i.Created,
                         WeekEnding = i.WeekEnding,
                         Status = s.staStatus
                     }
                   ).Skip(_pageIndex * _pageSize).Take(_pageSize);

      }

   }
{

Итак, я хочу вернуть IQueryable из моего сервиса, чтобы я мог фильтр из кода клиента. Но проблема, которую я придумываю это ошибки метода FilterInvoices с "Не поддерживается перевод в sql "из-за метода GetInvoice который используется для возврата объекта Invoice (это слой сверху (слой LInq2 sql), а не сущность счета Linq2sql.

Так как мне вернуть IQueryable из моего сервиса с этой структурой ?? Также как сортировать и возвращать IQureyable в репозитории GetInvoices.

Надеюсь, это имеет смысл.

Malcolm

Ответы [ 3 ]

1 голос
/ 23 февраля 2010

linq2sql считает, что GetInvoice (внутри GetInvoices) является хранимой процедурой. Один из способов обойти это

var query = from inv in _dbctx.Invoices orderby inv.invInvoiceDate descending select inv ;

хотя это передало бы назад объекты, сгенерированные вашим текстом данных. Если вы хотите заполнить пользовательские объекты, вы можете выполнить итерацию по коллекции, создавая собственные объекты Invoice и заполняя их.

foreach(var inv in query) { somelist.Add(new MyCustomInvoince() { id = inv.id ... }

РЕДАКТИРОВАТЬ: выше будет возвращать список. Используйте следующее, чтобы вернуть IQueryable

return from item in query
    select GetInvoice(item);

Разница в том, что на этом этапе вы используете Linq2Objects, и этот провайдер будет знать, как вызвать GetInvoice

1 голос
/ 24 февраля 2010

Вы не можете запросить с помощью LTS (Linq to SQL) чего-то построенного «поверх» уровня LTS. Причина в том, что слой сущностей LTS является отображением содержимого вашей базы данных, а выполняемый вами запрос «просто» переводится в SQL.

Я лично использую другой подход, чтобы сохранить независимость между моими слоями ...

Я создаю интерфейсов , соответствующих моим объектам LTS, и использую метод Cast <> () , чтобы мой репозиторий возвращал интерфейс вместо конкретной реализации.

Работает отлично.

Вам необходимо расширить базовую сущность (без pb, поскольку это частичный класс):

partial class Employee : IEmployee

И вам нужно это свойство в вашем хранилище:

public IQueryable<IEmployee> Query
{
    get
    {
        return this._context.Employees.Cast<IEmployee>();

    }
}

Исходя из этого, вы можете написать общий репозиторий, но это другая история (более сложная)

0 голосов
/ 23 февраля 2010

Это просто не в моей голове, но вы можете попробовать:

from i in _service.GetInvoices().AsEnumerable()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...