我是MVC 5和EF 6的新手,而且我很難理解EF如何工作。我首先使用數據庫,並使用Visual Studio創建edmx文件。請多多包涵,如果是長,我真的想學習EF 6 MVC 5使用MVC 5和實體框架掙扎6
所以在我的數據庫中,我第一次有這種
Book
-----
Id
Name
AttributeType (ex : Book Size, Book Content, Book Cover)
-------------
Id
Name
Attribute (ex : Pocket, Mature, Young Reader, Hard Cover, Soft Cover) (FK to AttributeType)
--------
Id
AttributeTypeId
Name
BookAttribute (FK to Book and Attribute, PK (AttributeId and BookId)
-------------
AttributeId
BookId
因此,使用數據庫,VS 2013會自動創建我的實體:
public partial class Book {
public int Id {get;set;}
public virtual ICollection<Attribute> Attributes { get; set; }
}
,並在我的DbContext
public virtual DbSet<Book> Books { get; set; }
,我加入了一些類
public enum BookAttributeEnum { BookSize = 1, CoverType = 2, BookAudience = 3 }
public partial class Book {
[NotMapped]
[Display(Name = "BookSize", ResourceType = typeof(Resources.Resources))]
public Attribute BookSize
{
get { return Attributes.FirstOrDefault(c => c.AttributeTypeId == (int) BookAttributeEnum.BookSize); }
}
[NotMapped]
[Display(Name = "CoverType", ResourceType = typeof(Resources.Resources))]
public Attribute CoverType
{
get { return Attributes.FirstOrDefault(c => c.AttributeTypeId == (int)BookAttributeEnum.CoverType); }
}
[NotMapped]
[Display(Name = "BookAudience", ResourceType = typeof(Resources.Resources))]
public Attribute BookAudience
{
get { return Attributes.FirstOrDefault(c => c.AttributeTypeId == (int)AttributeTypeEnum.BookAudience); }
}
}
,在我EditorTemplate的書:
<div class="form-group">
@Html.LabelFor(model => model.BookSize, new { @class = "control-label col-md-2" })
<div class="col-lg-8">
@Html.DropDownListFor(model => model.BookSize.Id, (IEnumerable<SelectListItem>)ViewData["BookSizes"], new { @class = "form-control m-bot15" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.CoverType, new { @class = "control-label col-md-2" })
<div class="col-lg-8">
@Html.DropDownListFor(model => model.CoverType.Id, (IEnumerable<SelectListItem>)ViewData["CoverTypes"], new { @class = "form-control m-bot15" })
</div>
</div>
<div class="form-group">
@Html.LabelFor(model => model.BookAudience, new { @class = "control-label col-md-2" })
<div class="col-lg-8">
@Html.DropDownListFor(model => model.BookAudience.Id, (IEnumerable<SelectListItem>)ViewData["BookAudiences"], new { @class = "form-control m-bot15" })
</div>
</div>
而且我BookContoller
public ActionResult Edit(int id)
{
var Db = new CArtEntities();
var attributes = Db.Attributes.ToList();
ViewData["BookSizes"] = attributes.Where(c => c.AttributeTypeId == (int)AttributeTypeEnum.BookSize).ToList()
.ToListItems(c => c.Id.ToString(), d => d.Name, true);
ViewData["CoverTypes"] = attributes.Where(c => c.AttributeTypeId == (int)AttributeTypeEnum.CoverType).ToList()
.ToListItems(c => c.Id.ToString(), d => d.Name, true);
ViewData["BookAudiences"] = attributes.Where(c => c.AttributeTypeId == (int)AttributeTypeEnum.BookAudience).ToList()
.ToListItems(c => c.Id.ToString(), d => d.Name, true);
var art = Db.Books
.Include("Attributes")
.Include("ApplicationUser")
.First(u => u.Id == id);
return View(art);
}
這似乎是在那裏我能不能找到一種方法使用實體框架
更新零件[HttpPost]
[ValidateAntiForgeryToken]
public async Task<ActionResult> Edit(Book model)
{
if (ModelState.IsValid)
{
var Db = new BookEntities();
// this is not a good idea, but i don't know how to do it correctly
var book = Db.Books
.Include("Attributes")
.Include("ApplicationUser")
.First(u => u.Id == id);
book.Name = model.Name;
Db.Entry(book).State = System.Data.Entity.EntityState.Modified;
List<int> listAttributes = new List<int>();
listAttributes.Add(Int32.Parse(Request["BookSize.Id"]));
listAttributes.Add(Int32.Parse(Request["CoverType.Id"]));
listAttributes.Add(Int32.Parse(Request["BookAudience.Id"]));
for (int i = book.Attributes.Count - 1; i >= 0; i--)
{
Attribute at = book.Attributes.ToList()[i];
if (!listAttributes.Contains(at.Id))
Db.Entry(at).State = EntityState.Deleted;
}
foreach (int i in listAttributes)
{
if (book.Attributes.FirstOrDefault(c => c.Id == i) == null)
{
Attribute at = new Attribute {Id = i};
book.Attributes.Add(at);
}
}
await Db.SaveChangesAsync();
return RedirectToAction("Index");
}
return View(model);
}
因此,我的問題ns:
- 保存時,是否需要重新獲取當前保存的對象 ?因爲我想我需要知道哪些屬性已被刪除,並添加了 。
- 我該如何爲書添加屬性? book.Attributes.Add(AT);當我做SaveChangesAsync()時,這行會引發一個錯誤,因爲它似乎要添加一個新的屬性 (這是不正確的,因爲它已經在數據庫中,並且 它有一個id,並且它引發ValidationError(Name is需要)
- 什麼是動態生成的書最好的辦法在我的編輯器模板的屬性
?還是我通過爲每個屬性類型創建
財產做是正確的?
我希望有人能幫助我我已經找了幾個小時怎麼做,但是到現在爲止都沒有成功。
謝謝
謝謝您的回覆,但Db.Attributes.Attach(在)我扔一個錯誤'與已經在ObjectStateManager存在相同的密鑰的對象。 ObjectStateManager不能使用相同的密鑰跟蹤多個對象。' – puntapret
@puntapret:你可以嘗試替換'屬性at = new Attribute {Id = i}; Db.Attributes.Attach(at);'通過'Attribute at = Db.Attributes.Find(i);'?我不知道你的代碼如何發生這種異常。 – Slauma
我改變了,現在它拋出我的錯誤:'無法更新EntitySet的「BookAttribute」,因爲它有一個DefiningQuery並沒有元素在元素的存在是爲了支持當前operation.'。這很奇怪,因爲BookAttribute表具有主鍵。 –
puntapret