我是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