Поскольку профиль связан с пользователями, а не с пользовательскими специальностями, было бы разумнее выполнить это с помощью двух запросов.
Получите ваши пользовательские особенности, как вы делали выше, затем возьмите эти userId и захватите их связанные профили (должно быть что-то вроде User.getProfile
в зависимости от того, как настроены ваши ассоциации).
Прямо сейчас у вас есть атрибуты UserSpecialties, настроенные так, чтобы они возвращали только specialty_id и title. Если вы добавите userId к этим атрибутам, вы можете использовать эти userId для запроса таблицы вашего профиля. Обещание затем хорошо работает для чего-то подобного, например:
UserSpecialties.findAll({...}).then((userSpecialties) => {
User.getProfile({where: {userId: userSpecialties.userId}, attributes: {'first_name', 'last_name'})
});
В зависимости от того, что вы конкретно пытаетесь сделать с информацией, вам, вероятно, придется немного ее подправить, но общая идея добавления в userId в качестве атрибута, а затем запрос вашей пользовательской таблицы для профилей с использованием userId из результата запроса UserSpecialties должен работать нормально для данных, которые вы хотите.
Несмотря на то, что, глядя на ваши модели, возможно, имеет смысл просто иметь профиль и пользователя в одной таблице, где у пользователя есть имя, фамилия, имя пользователя и статус. Поскольку в Профиле нет много других вещей, а затем, если вам нужны определенные вещи для userProfile, вы можете использовать области действия в вашей пользовательской модели.
[Обновление]
Поскольку L2E используется, необходимо сохранить все связанные объекты сначала, прежде чем можно будет сохранить основной объект. Который имеет смысл иначе, Вы создали бы (в моем примере) художника без, он - объект контакта. Это не позволяется проектированием баз данных.
[/Обновление]
Вот моя реализация, которая работала.
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Create([Bind(Exclude = "Id")] Artist artist, [Bind(Prefix = "Contact")] Contact contact, [Bind(Prefix = "Country")] Country country, [Bind(Prefix = "ContactRelationship")] ContactRelationship contactRelationship)
{
ViewData["Countries"] = new SelectList(new CountryService(_msw).ListCountries().OrderBy(c => c.Name), "ID", "Name");
ViewData["ContactRelationships"] = new SelectList(new ContactRelationshipService(_msw).ListContactRelationships().OrderBy(c => c.ID), "ID", "Description");
country = _countryService.GetCountryById(country.ID);
contact.Country = country;
contactRelationship = _contactRelationshipService.GetContactRelationship(contactRelationship.ID);
contact.ContactRelationship = contactRelationship;
if(_contactService.CreateContact(contact)){
artist.Contact = contact;
if (_service.CreateArtist(artist))
return RedirectToAction("Index");
}
return View("Create");
}
И затем в моем ContactRepository:
public Contact CreateContact(Contact contact)
{
_entities.AddToContact(contact); //no longer throws the exception
_entities.SaveChanges();
return contact ;
}
Я также нашел на этом веб-сайте, который лучше сохранять тот же контекст всюду по приложению, таким образом, я теперь использую специальный класс Данных для этого:
Rick Strahl и Samuel Maecham учили меня, что необходимо сохранить datacontext на пользователя на запрос. Что означает помещать его в HttpContext для веб-приложений. Считайте все об этом здесь
public class Data
{
public static MyDBEntities MyDBEntities
{
get
{
if (HttpContext.Current != null && HttpContext.Current["myDBEntities"] == null)
{
HttpContext.Current["myDBEntities"] = new MyDBEntities ();
}
return HttpContext.Current["myDBEntities"] as MyDBEntities;
}
set {
if(HttpContext.Current != null)
HttpContext.Current["myDBEntities"] = value;
}
}
}
Я видел это прежде, Вам, вероятно, придется преобразовать Поле ссылки в EntityKey прежде, чем сохранить и затем Загрузка это после его сохраненного. Попробуйте этот код вместо этого:
public Contact CreateContact(Contact contact){
contact.ConvertContactRelationToReference();
_entities.AddToContact(contact);
//throws the exception
_entities.SaveChanges();
contact.ContactRelation.Load();
return contact;
}
public partial class Contact
{
public void ConvertContactRelationToReference()
{
var crId = ContactRelation.Id;
ContactRelation = null;
ContactRelationReference.EntityKey = new EntityKey("MyEntities.ContactRelations", "Id", crId);
}
}
Конечно, часть этого кода, возможно, должна быть изменена в зависимости от Вашей точной структуры базы данных.