#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
notSample
— Лучшее предположение, что вы хотите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 таким образом, поэтому мне интересно, есть ли какая-то разница между ними, которая заставляет его работать в одном, но не в другом.