Как исправить ‘Системы.Коллекции.Общий.IEnumerables’ Существует явное преобразование. Вам не хватает приведения?

#asp.net-mvc

#asp.net-mvc

Вопрос:

Я создаю веб-API в MVC. База данных (пока) простая, всего три таблицы. Однако я не могу присоединиться к ним. Я пробовал три разных метода объединения таблиц в контроллере, и все они возвращают одну и ту же ошибку, которая:

Невозможно скрыть тип (что-то *) в ‘Systems.Коллекции.Общий.IEnumerables<SalesDbApi.Sample>’ Явное преобразование существует. Вам не хватает приведения?

(* Часть «что-то» отличается в зависимости от того, как происходит объединение, но остальная часть сообщения остается неизменной, поэтому я предполагаю, что это соответствующая часть.)

Я предполагаю, что что-то не так с тем, как я настроил свои отношения сущностей в Linq, потому что, если я не выполняю соединение и просто выбираю все из образца, я получаю следующий JSON обратно:

 {"SampleId":10,"Barcode":"863760","CreatedAt":"2016-01-25T00:00:00","CreatedBy":10,"StatusID":3,"User":null,"Status":null}
  

Пользователь и статус не являются полями в таблице примеров. Это имена таблиц, с которыми я пытаюсь связать, поэтому я бы не ожидал, что они появятся.

Есть идеи о том, что я сделал не так?

Вот мои три модели:

Users.cs

 namespace SalesDbApi
{
    using System;
    using System.Collections.Generic;

    public partial class User
    {
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
        public User()
        {
            this.Samples = new HashSet<Sample>();
        }

        public int UserId { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }

        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
        public virtual ICollection<Sample> Samples { get; set; }
    }
}
  

Statuses.cs

 namespace SalesDbApi
{
    using System;
    using System.Collections.Generic;

    public partial class Status
    {
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2214:DoNotCallOverridableMethodsInConstructors")]
        public Status()
        {
            this.Samples = new HashSet<Sample>();
        }

        public int StatusId { get; set; }
        public string Status1 { get; set; }

        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA2227:CollectionPropertiesShouldBeReadOnly")]
        public virtual ICollection<Sample> Samples { get; set; }
    }
}
  

Samples.cs

 namespace SalesDbApi
{
    using System;
    using System.Collections.Generic;

    public partial class Sample
    {
        public int SampleId { get; set; }
        public string Barcode { get; set; }
        public Nullable<System.DateTime> CreatedAt { get; set; }
        public int CreatedBy { get; set; }
        public int StatusID { get; set; }

        public virtual User User { get; set; }
        public virtual Status Status { get; set; }
    }
}
  

Вот код от контроллера

SalesUsersController.cs

 using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Web.Http;
using SalesDbApi;

namespace SalesProject.Controllers
{
    public class SalesUsersController : ApiController
    {
        webapitestdbEntities1 db = new webapitestdbEntities1();

        public IEnumerable<Sample> Get()
        {

            {
               db.Configuration.ProxyCreationEnabled = false;

                var query = from x in db.Samples
                            join q in db.Users
                            on x.CreatedBy equals q.UserId
                            select q.FirstName;
                return query.ToList();
            }
        }
  

Комментарии:

1. Ваш запрос выбирает только FirstName свойство User not Sample — Лучшее предположение, что вы хотите select x (нет select q.FirstName ), хотя неясно, зачем вам нужен join здесь, если вы хотите вернуть только коллекцию Sample , если вы хотите вернуть другие свойства User , тогда вам нужно спроецировать результаты в модель представления, содержащую эти свойства.

2. Я попытался выбрать несколько полей, но, похоже, все получили одну и ту же ошибку, поскольку она извлекается из объединенной таблицы. Когда я попытался выбрать x, я получил результаты, упомянутые выше ({«SampleId»:10,»Barcode»:»123″,»CreatedAt»:»2016-01-25T00:00:00″,»CreatedBy»:10,»StatusID»:3,»User»:null,»Статус»: null}) Все эти поля взяты из примерной таблицы, за исключением user и status , которые не являются полями ни в одной таблице; они являются ссылками на другие таблицы, заданные как общедоступные виртуальные классы в модели sample.cs общедоступный виртуальный пользователь User { get; set; } общедоступный виртуальный статус Status { get; set; }

3. Прочитайте мой первый комментарий еще раз. Если вам нужны поля из нескольких таблиц, вы не можете вернуть коллекцию Sample — вам нужно вернуть коллекцию модели, которая содержит нужные вам свойства — select new MyModel { SampleId = x.SampleId, FirstName = q.FirstName, ..... }

4. Как мне настроить эту модель?

5. Оно будет просто содержать каждое из свойств Sample , User и Status которые вы хотите отобразить в представлении (я не знаю, какое из них вам нужно)

Ответ №1:

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

Комментарии:

1. Они оба есть. Если я попытаюсь вернуть данные из любой отдельной таблицы через контроллер, он вернется. Ошибка возникает только при попытке объединить таблицы.

2. возможно, таблица соединений не является связью с данными, в конечном итоге соединение не найдено. Попробуйте присоединиться вручную в SQL-запросе, есть какие-либо данные или нет?

3. Да, даже ручные соединения выдавали мне ту же ошибку. У меня это уже работало раньше, когда я делал веб-приложения в MVC. Я впервые создаю веб-api таким образом, поэтому мне интересно, есть ли какая-то разница между ними, которая заставляет его работать в одном, но не в другом.