Загрузить DataGridView из запроса LINQ to SQL - PullRequest
0 голосов
/ 02 июня 2018

Я получаю сообщение об ошибке при загрузке представления данных из запроса LINQ.

Я делаю запрос для загрузки данных из 3 таблиц, но всегда получаю сообщение "Не удается неявно преобразовать List в IQueryable. Я знаюприведение существует, но не может его выяснить.

Итак, во-первых, я добавил в форму класс, который будет иметь в качестве свойств значения, которые я хочу иметь для каждой строки моего объединения:

public class ListofModuleUser
{
    public string User { get; set; }
    public string Modulo { get; set; }
    public bool Read { get; set; }
    public bool Write { get; set; }
    public bool Create { get; set; }
    public bool Delete { get; set; }
    public bool Navigate { get; set; }
}

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

public IQueryable<ListofModuleUser> LoadData()
{
    var ctx = new JEntities();
    var fillusers = (from mu in ctx.tblModuloUsers.AsQueryable()
                     join u in ctx.tblUsers on mu.UserID equals u.UserID
                     join m in ctx.tblModuloes on mu.ModuloID equals m.ModuloID
                     select new
                     {
                         User = u.Username,
                         Modulo = m.Moduloname,
                         Read = mu.CanRead,
                         Write = mu.CanWrite,
                         Create = mu.CanCreate,
                         Delete = mu.CanDelete,
                         Navigate = mu.CanNavigate
                     }).ToList();

    return fillusers; //---> Obviously the error occours here! 
}

А затем, при событии Load, я получаю свой список и заполняюмое сетевое представление:

private void MapUserToModulos_List_Load(object sender, EventArgs e)
{
     usersmodules_datagrid.DataSource = LoadData();
}

Может ли кто-нибудь помочь мне выяснить, какой бросок я должен использовать, поскольку я перепробовал все возможные приведения (ToList, Array, AsEnumerable, AsQueryable ...)

Ответы [ 2 ]

0 голосов
/ 02 июня 2018

В вашем коде есть 3 важные проблемы.

  1. Прежде всего, IQueryable<T> представляет запрос, который должен быть выполнен и результаты загружены в память.Вы не хотите этого, результаты должны быть материализованы, и клиент не должен знать о запросе.Итак, измените ваш тип возвращаемого значения на IEnumerable<T>:

    public IEnumerable<ListofModuleUser> LoadData()
    
  2. Ваш метод утверждает, что возвращает ListofModuleUser, но вы проецируете на анонимный объект, измените его так, чтобы он возвращал фактический класс:

    select new ListofModuleUser
    {
        User = u.Username,
        Modulo = m.Moduloname,
        Read = mu.CanRead,
        Write = mu.CanWrite,
        Create = mu.CanCreate,
        Delete = mu.CanDelete,
        Navigate = mu.CanNavigate
    }
    
  3. Вы не утилизируете создаваемый экземпляр DbContext, который может легко привести к утечке памяти.Вы всегда должны использовать оператор using вокруг IDisposable объектов:

    using (var ctx = new JEntities())
    {
        ...
    }
    

Собрав все это вместе, ваш код должен выглядеть следующим образом:

public IEnumerable<ListofModuleUser> LoadData()
{
    using (var ctx = new JEntities())
    {
        return (from mu in ctx.tblModuloUsers.AsQueryable()
                join u in ctx.tblUsers on mu.UserID equals u.UserID
                join m in ctx.tblModuloes on mu.ModuloID equals m.ModuloID
                select new ListofModuleUser
                {
                    User = u.Username,
                    Modulo = m.Moduloname,
                    Read = mu.CanRead,
                    Write = mu.CanWrite,
                    Create = mu.CanCreate,
                    Delete = mu.CanDelete,
                    Navigate = mu.CanNavigate
                 })
                 .ToList();
    }
}

Я бы также предложил переименовать ListofModuleUser в ModuleUser, поскольку класс представляет одного пользователя модуля.

0 голосов
/ 02 июня 2018

Ваш метод утверждает, что возвращает IQueryable<T>:

public IQueryable<ListofModuleUser> LoadData()

Но вы пытаетесь вернуть List<T>:

var fillusers = ....ToList();
return fillusers;

Если вы хотите вернуть списокизмените тип возвращаемого значения метода:

public IList<ListofModuleUser> LoadData()

Или, если вы хотите вернуть IQueryable, удалите .ToList() из вашего запроса LINQ.

Кроме того, ваш тип возвращаемого значения - это определенный класс:

ListofModuleUser

Но вы запрашиваете анонимный объект:

select new
{
    User = u.Username,
    Modulo = m.Moduloname,
    Read = mu.CanRead,
    Write = mu.CanWrite,
    Create = mu.CanCreate,
    Delete = mu.CanDelete,
    Navigate = mu.CanNavigate
}

Вы должны выполнить запрос к правильному типу:

select new ListofModuleUser
{
    User = u.Username,
    Modulo = m.Moduloname,
    Read = mu.CanRead,
    Write = mu.CanWrite,
    Create = mu.CanCreate,
    Delete = mu.CanDelete,
    Navigate = mu.CanNavigate
}

Примечание: ListofModuleUser - довольно неинтуитивное имя для одного объекта.То, что вы создаете, в основном называется «Список списка пользователей модуля».Возможно, класс просто нужно назвать ModuleUser?

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