Какой шаблон использовать для доступа к данным в приложении WPF / MVVM - PullRequest
1 голос
/ 07 февраля 2011

У меня есть приложение для управления задачами, которое в настоящее время использует класс для доступа к данным с использованием Linq-to-SQL;Я хочу перенести доступ к данным в отдельное решение в проекте.Причина, по которой я хочу это сделать, заключается в подготовке к двум вещам.Во-первых, это создание службы, которая будет работать на базе данных «Сервер» (это просто ПК с выигрышем 7), которая будет периодически запрашивать задания и отправлять напоминания по электронной почте о тех, которые должны быть выполнены.Во-вторых, изменить доступ к данным в WCF, чтобы я мог получать доступ к задачам из WP7 (после того, как они будут в Verizon)

Возвращаемые задачи определяются рядом пользовательских элементов управления, связанных с моделью представления.В настоящее время iQueryable состоит из ряда операторов, которые сужают выбор в соответствии с элементами с привязкой к данным.Затем запрос заказывают другие участники.После того, как я удалю доступ к данным из решения, чтобы он не имел доступа к членам viewmodels, мне нужно будет передать относительно большое количество параметров, и я не уверен, каким будет правильный способ сделать это.Я могу придумать следующие способы:

  1. Просто создайте метод с дюжиной или более параметров (мне говорят, что это плохая практика)
  2. Создайте объект, содержащий все параметрыи передайте это (мне кажется, это не сильно отличается от первого варианта)
  3. Создайте класс в решении для доступа к данным, а затем создайте его экземпляр и установите каждое из его свойств перед вызовом метода, который будет возвращатьiQueryable (или ObservableCollection), но я читал, что эта практика "плохо пахнет"

Я довольно зеленый в ООП и WPF, и это простое приложение - самое сложное, которое я создал.Я чувствую, что мне не хватает шаблона или практики, предложений?

Пример того, как строится запрос:

IQueryable<Issue> issuesQuery;

// Will select all items
issuesQuery = from i in db.Issues
      select i;

// Filters out pending issues
issuesQuery = issuesQuery.Where(i => i.IssIsPending == showPendingTasks);

// Filters out closed issues if they are not to be shown
if (includeClosedIssues == false) {
    issuesQuery = issuesQuery.Where(i => i.IssIsClosed == false);
}

// Filters out Regular Tasks if they are not to be shown
if (showTasks == false) {
    issuesQuery = from i in issuesQuery
             where i.IssIsOnStatusBoard == true
             select i;
}

// More filters are here

// Order the results      
issuesQuery = issuesQuery.OrderByDescending(
    i => i.IssIsSticky).ThenBy(
    i=>!i.IssDueDate.HasValue).ThenBy(
    i => i.IssDueDate).ThenBy(
    i => i.IssUrgency);

// an iQueryable is returned but is then converted to an ObservableCollection
return issuesQuery;

1 Ответ

1 голос
/ 08 февраля 2011

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

Вы можете использовать два разных решения.

1.WCF DataServices.

Добавить -> Новый элемент -> Wcf Data Service.

Затем укажите имя DataContext и установите права доступа.

public class WcfDataService1 : DataService<TestEntities>
{
    public static void InitializeService(DataServiceConfiguration config)
    {
        config.DataServiceBehavior.MaxProtocolVersion = DataServiceProtocolVersion.V2;
        config.SetEntitySetAccessRule("*", EntitySetRights.All);
        config.SetServiceOperationAccessRule("*", ServiceOperationRights.AllRead);
    }

    /// <summary>
    /// Example of custom operations
    /// </summary>
    [WebGet]
    public IQueryable<Item> ItemsById(int id)
    {
        return this.CurrentDataSource.Items.Where(i => i.Id == id);
    }
}

В клиентском приложении добавьте новую ссылку на службу, и после этого вы сможете использовать службу, как если бы она была локальной базой данных:

var proxy = new TestEntities(new Uri("http://localhost:8513/WcfDataService1.svc/"));
var items = proxy.Items.Where(i => i.Id > 2 && i.Title.Contains("x1"));
var item2 = proxy.Execute<Item>(new Uri("ItemsById?Id=1", UriKind.Relative)).FirstOrDefault();

Преимущество: вам не нужно писать многочисленные методы, такие как GetItemsById, GetItemsByYear, GetTenItems и т.д .;Вы можете создать фильтр запроса на стороне клиента.

Недостатки: операции сервиса не статически типизированы;трудно вызывать пользовательские операции, особенно если у них много параметров;Есть много проблем, если использовать пользовательские объекты вместо сущностей;

2.Службы WCF

Добавить -> Новый элемент -> Служба Wcf

Класс хранилища:

public class IssuesRepository
{
    public static List<Issue> GetIssues()
    {
        //creating a new connection will not cause overhead because there is a pool of connections
        using (var db = new TestEntities()) 
        {
            List<Expression<Func<Issue, bool>>> filters = new List<Expression<Func<Issue, bool>>>();

            filers.Add(i => i.IssIsPending == showPendingTasks);

            if (includeClosedIssues == false)
                filers.Add(i => i.IssIsClosed == false);

            if (showTasks == false)
                filers.Add(i => i.IssIsOnStatusBoard == true);


            IQueryable<Issue> issuesQuery = db.Items.AsQueryable();

            foreach (var filter in filters)
                issuesQuery = issuesQuery.Where(filter);

            issuesQuery = from i in issuesQuery
                          orderby i.IssIsSticky descending, !i.IssDueDate.HasValue ascending, i.IssDueDate, i.IssUrgency
                          select i;

            return issuesQuery.ToList(); //it will be serialized in any case
        }
    }
}

Служба:

public class Service1 : IService1
{
    public List<Issue> GetIssues()
    {
        return IssuesRepository.GetIssues();
    }
}

Преимущества: независимо от протокола;обеспечить сеансы, безопасность, транзакции.

Итак, в заключение я рекомендую использовать DataServices, если вам нужна только функциональность CRUD, и общие службы WCF, если вы используете набор операций со сложной логикой.

...