Entity framework 4 EF 4 CTP 5保存多对多导航属性
我使用的是EF4 CTP5,无法将记录保存回数据库。我有Contact和ContactType实体。正如文章标题所述,我在表之间设置了多对多导航属性 问题在于验证ContactType值。ModelState.IsValid为false,因为它无法将从表单(ContactType id的字符串数组)传回的值转换为ContactType对象 波科氏Entity framework 4 EF 4 CTP 5保存多对多导航属性,entity-framework-4,asp.net-mvc-3,entity-framework-ctp5,Entity Framework 4,Asp.net Mvc 3,Entity Framework Ctp5,我使用的是EF4 CTP5,无法将记录保存回数据库。我有Contact和ContactType实体。正如文章标题所述,我在表之间设置了多对多导航属性 问题在于验证ContactType值。ModelState.IsValid为false,因为它无法将从表单(ContactType id的字符串数组)传回的值转换为ContactType对象 波科氏 public partial class Contact { public Contact() {
public partial class Contact
{
public Contact()
{
this.ContactTypes = new HashSet<ContactType>();
}
// Primitive properties
public int ContactId { get; set; }
public string ContactName { get; set; }
// Navigation properties
public virtual ICollection<ContactType> ContactTypes { get; set; }
}
public partial class ContactType
{
public ContactType()
{
this.Contacts = new HashSet<Contact>();
}
// Primitive properties
public int ContactTypeId { get; set; }
public string Name { get; set; }
// Navigation properties
public virtual ICollection<Contact> Contacts { get; set; }
}
看法
因此,问题似乎很清楚,但我似乎找不到解决方案。我已尝试手动将ContactType id转换为ContactType对象,并将其添加到传递到编辑函数(称为“Contact”)的Contact对象中:
但这并没有起作用。我还使用
ModelState.SetModelValue("ContactTypes", val);
这也不管用。我觉得我缺少了一些基本的东西。有什么想法吗
谢谢,Steve在这方面做了更多的工作之后,我找到了一个解决办法。基本上,我必须忽略验证错误,然后手动删除现有的ContactType,然后添加用户选择的ContactType。我确实尝试为Contact.ContactTypes属性构建自定义验证器,但ContactType对象始终传递给该方法;我我从未见过字符串数组。无可否认,这是我构建的第一个自定义验证器,所以可能我遗漏了一些东西 不管怎样,我最终得到的编辑方法是:
//
// POST: /Contact/Edit/5
[HttpPost]
public virtual ActionResult Edit(Contact contact)
{
// clear up ModelState.IsValid for contact type
ModelState.Remove("ContactTypes");
if(ModelState.IsValid)
{
// remove all contact types for contact
Contact dummy = context.Contacts.Single(c => c.ContactId == contact.ContactId);
if(dummy.ContactTypes.Count > 0)
{
dummy.ContactTypes.Clear();
context.Entry(dummy).State = EntityState.Modified;
context.SaveChanges();
}
context.Detach(dummy);
context.Contacts.Attach(contact);
// add currently selected contact types, then save
string[] ids = this.HttpContext.Request.Form["ContactTypes"].Split(',');
for(int i = 0; i< ids.Length; i++)
{
int x = Convert.ToInt32(ids[i]);
ContactType selectedType = context.ContactTypes.Single(t => t.ContactTypeId == x);
contact.ContactTypes.Add(selectedType);
}
context.Entry(contact).State = EntityState.Modified;
context.SaveChanges();
ViewBag.Message = "Save was successful.";
}
ViewData["ContactTypes"] = contact.ContactTypes.Select(t => t.ContactTypeId);
ViewData["ContactTypesAll"] = GetTypesList();
return View(contact);
}
ModelState.Values.ElementAt(2).Value
{System.Web.Mvc.ValueProviderResult}
AttemptedValue: "5"
Culture: {en-US}
RawValue: {string[1]}
ModelState.Values.ElementAt(2).Errors[0]
{System.Web.Mvc.ModelError}
ErrorMessage: ""
Exception: {"The parameter conversion from type 'System.String' to type 'ProjectObjects.ContactType' failed because no type converter can convert between these types."}
contact.ContactTypes.Clear();
string[] ids = this.HttpContext.Request.Form["ContactTypes"].Split(',');
for(int i = 0; i< ids.Length; i++)
{
int x = Convert.ToInt32(ids[i]);
ContactType selectedType = context.ContactTypes.Single(t => t.ContactTypeId == x);
contact.ContactTypes.Add(selectedType);
}
context.ChangeTracker.DetectChanges();
ModelState.SetModelValue("ContactTypes", val);
//
// POST: /Contact/Edit/5
[HttpPost]
public virtual ActionResult Edit(Contact contact)
{
// clear up ModelState.IsValid for contact type
ModelState.Remove("ContactTypes");
if(ModelState.IsValid)
{
// remove all contact types for contact
Contact dummy = context.Contacts.Single(c => c.ContactId == contact.ContactId);
if(dummy.ContactTypes.Count > 0)
{
dummy.ContactTypes.Clear();
context.Entry(dummy).State = EntityState.Modified;
context.SaveChanges();
}
context.Detach(dummy);
context.Contacts.Attach(contact);
// add currently selected contact types, then save
string[] ids = this.HttpContext.Request.Form["ContactTypes"].Split(',');
for(int i = 0; i< ids.Length; i++)
{
int x = Convert.ToInt32(ids[i]);
ContactType selectedType = context.ContactTypes.Single(t => t.ContactTypeId == x);
contact.ContactTypes.Add(selectedType);
}
context.Entry(contact).State = EntityState.Modified;
context.SaveChanges();
ViewBag.Message = "Save was successful.";
}
ViewData["ContactTypes"] = contact.ContactTypes.Select(t => t.ContactTypeId);
ViewData["ContactTypesAll"] = GetTypesList();
return View(contact);
}
public void Detach(object entity)
{
((System.Data.Entity.Infrastructure.IObjectContextAdapter)this).ObjectContext.Detach(entity);
}