Как сделать редактируемый запрос выбора EF для управления сеткой DevExpress?

Я работаю над приложением для кинотеатров, которое позволяет пользователям просматривать фильмы, места в кинотеатрах и позволяет им покупать или бронировать билеты. Если пользователь забронировал билет онлайн, то билет должен быть активирован в течение 12 часов продавцом, который также использует ту же программу. Мне нужно показать информацию о билетах в сетке и сделать редактируемой. Вот мои классы базы данных, которые должны быть включены в запрос и иметь связь с классом Sale. (Я хочу выбрать объекты из класса «Продажа», который включает в себя связанные классы: «Билет», «Клиент», «Фильм», «Статус» и «Салон».

Класс продажи:

public class Sale
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int ID { get; set; }

    [ForeignKey("CustomerId")]
    public virtual Customer Customer { get; set; }
    public int CustomerId { get; set; }

    [ForeignKey("StatusId")]
    public virtual Status Status { get; set; }
    public int StatusId { get; set; }

    public virtual Seller Seller { get; set; }

    public DateTime SellDate { get; set; }

    public double Price { get; set; }

    [ForeignKey("TicketID")]
    public virtual Ticket Ticket { get; set; }
    public int TicketID { get; set; }
}

Класс билетов:

public class Ticket
{
    public Ticket()
    {
        Seats = new List<Seat>();
    }
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int ID { get; set; }

    [ForeignKey("MovieId")]
    public virtual Movie Movie { get; set; }
    public int MovieId { get; set; }

    public virtual List<Seat> Seats { get; set; }

    public virtual TimeSpan SeanceTime { get; set; }

    public bool IsActive { get; set; }

    public DateTime BuyDate { get; set; }

    [ForeignKey("SaloonId")]
    public virtual Saloon Saloon { get; set; }
    public int? SaloonId { get; set; }

    public string TicketNumber { get; set; }
}

Класс клиента:

public class Customer
{
    public Customer()
    {
        Sales = new List<Sale>();
        CreditCards = new List<CreditCard>();
    }
    [Key]
    public int UserID { get; set; }

    public virtual List<Sale> Sales { get; set; }

    public virtual User User { get; set; }

    [DataType(DataType.CreditCard)]
    public virtual List<CreditCard> CreditCards { get; set; }
}

Класс пользователя:

 public class User
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int ID { get; set; }

    public string Name { get; set; }

    public string Surname { get; set; }
}

Класс статуса (содержит информацию о билетах. Куплены или зарезервированы.)

  public class Status
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int ID { get; set; }

    public bool IsRez { get; set; }

    public bool IsBuy { get; set; }

    public bool IsCancel { get; set; }

    public bool IsPaid { get; set; }
}

Класс салона:

public class Saloon
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int ID { get; set; }

    public string Name { get; set; }

    public double salePrices { get; set; }
}

Класс фильма:

public class Movie
{
    [Key]
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int ID { get; set; }

    public string Name { get; set; }
}

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

var Source = entities.Sales.Where(w => w.Ticket.Saloon.CinemaPlace.ID == seller.CinemaPlace.ID).Select(s => new
        {
            CustomerName = s.Customer.User.Name,
            CustomerSurname = s.Customer.User.Surname,
            SalePrice = s.Price,
            s.Status.IsBuy,
            s.Status.IsCancel,
            s.Status.IsPaid,
            s.Status.IsRez,
            MovieName = s.Ticket.BuyDate,
            s.Ticket.Movie.Name,
            SaloonName = s.Ticket.Saloon.Name,
            s.Ticket.SeanceTime,
            s.Ticket.TicketNumber
        }).ToList();

        RezervationsGrid.DataSource = Source3; 

Но в сетке данные нельзя было редактировать. Затем я попытался присоединиться к каждой отдельной таблице, используя запросы Linq to Entities, но это тоже не помогло. Есть ли способ создать источник данных из моих связанных объектов, который позволяет редактировать в сетке? Спасибо.


person Fethi Tekyaygil    schedule 20.06.2017    source источник


Ответы (1)


Анонимные типы (те, которые можно объявить с помощью оператора new в методе Select) не могут иметь в .NET свойства, доступные для записи. Вот почему сетка не редактируется. Чтобы воспользоваться преимуществами редактирования на месте, необходимо создать экземпляры объектов реального типа CLR.

Для этого вы можете объявить специальный класс ViewModel с общедоступными свойствами, которые вы должны заполнить значениями в методе Select, используя инициализатор объекта.

.Select(s => new SaleViewModel() { 
  CustomerName = s.Customer.User.Name, 
  SalePrice = Price 
})

Обратите внимание, что вы не должны перемещать логику инициализации свойства в конструктор ViewModel, чтобы использовать его таким образом:

.Select(s => new SaleViewModel(s))

Инициализатор объекта — это дерево выражений, которое Entity Framework может преобразовать в SQL-запрос. Конструктор — это просто ссылка на метод, поэтому Entity Framework отклонит такое выражение. Если вы хотите использовать этот подход, вам нужно будет вызвать метод ToList перед методом Select.

SaleViewModel может иметь метод, принимающий класс DbContext для сохранения изменений.

Вы также можете выбрать экземпляры Sale и использовать сложные пути свойств в именах полей столбцов (например, «Customer.User.Name»). Это, вероятно, может помочь вам упростить логику сохранения, так как вам не нужно будет искать модель, специфичную для определенной модели представления, и копировать измененные значения свойств.

person Uranus    schedule 22.06.2017