我正在尝试在数据库中创建一个新对象,该对象将根据DropDownList的选择获取数据库条目的值。
在下面的示例中,我想要一个新的“Domena”对象来保存属于类TLD的属性“Cena”的值,已创建属性“Cena”并且它在数据库中作为十进制值。当从DropDownList中选择TLD时,它应该从TLD类中获取“Cena”的值。
这是Domena Class模型:
public class Domena
{
public int DomenaID { get; set; }
public int TLDID { get; set; } // foreign id
public int KlientID { get; set; }
// irrelevant code omitted
public decimal Cena { get; set; } // value which should be copied from "Cena" from TLD CLASS
public virtual TLD TLD { get; set; }
public virtual Klient Klient { get; set; }
}
以下是TLD类:
public class TLD
{
public int TLDID { get; set; }
public string Typ { get; set; }
public decimal Cena { get; set; }
public virtual ICollection<Domena> Domeny { get; set; }
}
我一直在看: http://blogs.msdn.com/b/adonet/archive/2011/01/30/using-dbcontext-in-ef-feature-ctp5-part-5-working-with-property-values.aspx 但我找不到自己的解决方案。我已经尝试过的是我的HTTP GET Create操作中的代码:
public ActionResult Create(TLD cena)
{
ViewBag.TLDID = new SelectList(db.TLDs, "TLDID", "Typ");
ViewBag.KlientID = new SelectList(db.Klienci, "KlientID", "Firma");
var model = new Domena
{
Cena = cena.Cena
};
return View();
}
但价值仍为0.00。我不知道如何做到这一点。
任何帮助都会受到欢迎。
bcr回答后编辑:
对不起,我没有提供所需的全部数据。我实际上修改了httpget和httpPost方法,因为我添加了另一个dropdownmenu。他们在这里:
HTTPGET:
public ActionResult Create()
{
ViewBag.TLDID = new SelectList(db.TLDs, "TLDID", "Typ");
ViewBag.KlientID = new SelectList(db.Klienci, "KlientID", "Firma");
ViewBag.StatusID = new SelectList(db.StatusDomeny, "StatusID", "Status");
return View();
}
HTTPPOST:
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create(Domena domena)
{
if (ModelState.IsValid)
{
db.Domeny.Add(domena);
db.SaveChanges();
return RedirectToAction("Index");
}
ViewBag.TLDID = new SelectList(db.TLDs, "TLDID", "Typ", domena.TLDID);
ViewBag.KlientID = new SelectList(db.Klienci, "KlientID", "Firma", domena.KlientID);
ViewBag.StatusID = new SelectList(db.StatusDomeny, "StatusID", "Status", domena.StatusID);
return View(domena);
}
我的观点如下:
<div class="editor-label">
@Html.LabelFor(model => model.TLDID, "TLD")
</div>
<div class="editor-field">
@Html.DropDownList("TLDID", String.Empty)
@Html.ValidationMessageFor(model => model.TLDID)
</div>
<div class="editor-label">
@Html.LabelFor(model => model.KlientID, "Klient")
</div>
<div class="editor-field">
@Html.DropDownList("KlientID", String.Empty)
@Html.ValidationMessageFor(model => model.KlientID)
</div>
<div class="editor-label">
@Html.LabelFor(model => model.StatusID, "Status")
</div>
<div class="editor-field">
@Html.DropDownList("StatusID", String.Empty)
@Html.ValidationMessageFor(model => model.StatusID)
</div>
截至目前,你可以看到我删除了与“Cena”相关的任何内容,因为我无法让它工作。
正如我在httpGet方法中理解的那样:
model.TldDropDown = new SelectList(db.TLDs, "TLDID", "Typ");
应该是
model.TldList = new SelectList(db.TLDs, "TLDID", "Typ");
基于你在CreateViewModel中的内容:
public IEnumerable<SelectListItem> TldList {get; set;}
我是对的吗?
然而,当我尝试这个时,我得到一个错误信息说:
无法将类型'System.Web.Mvc.SelectList'隐式转换为IEnumearble。存在显式转换。你错过了演员吗?
也许更多解释我正在努力实现的目标:
我有Domena对象的Create页面。有一个DropDownList,列出了TLD.Typ列出的db.TLD的TLD列表。我希望我的httpGet / httpPost方法知道如果让我们说TLDID = 1(它显示来自DropDownList的TLD.Typ值),那么它应该将属于TLDID = 1的“Cena”值赋给Domena.Cena属性
希望能更好地解释它。
答案 0 :(得分:1)
感谢您的澄清,它有所帮助。那么您的视图是否与Domena
实体绑定为模型?这不在您的视图示例中,但我会假设。
基本上,一旦您获得用户选择的TLD ID,您就需要从上下文中获取TLD实体,并且该TLD实体保存您希望填充新Domena对象属性的Cena值。我不确定你是否希望在屏幕上放置Cena值,但是你可以将它作为DomenaViewModel
的属性并在POST动作中设置它,在你保存之后新的Domena
到数据库。
假设Domena
类是一个实体,将实体用作视图模型并不是很好,正如这里已多次讨论的那样。一般方法似乎是将DomenaViewModel
类或DomenaDto
类用作视图模型。然后,根据需要将适当的字段映射到视图模型和实体。 AutoMapper
是帮助自动化和组织此过程的常用选项;我使用ValueInjecter.
在这个特定的例子中,手动操作应该足够简单来说明这一点。
另一件事是ViewBag
用于SelectLists
但ViewBag
从未在View
中引用。我会在这里完全使用ViewBag
并坚持使用ViewModel
方法。我会保持简单,专注于TLD和Domena类,以及创建操作所需的内容。类似的方法将用于其他下拉列表和实体。
请注意,您需要注意不要向DB添加另一个Domena
,就像已经存在的那个(具有所有相同的外键和值),除非你是这样的特别想做。基于斯科特艾伦article的这种下拉式方法。
public class DomenaViewModel
{
public List<TLD> Tlds {get; set;}
public int SelectedTldId { get; set; }
public IEnumerable<SelectListItem> TldItems
{
get { return new SelectList(Tlds, "TLDID", "Typ"); }
}
// irrelevant code omitted
}
[HttpGet]
public ActionResult Create()
{
var model = new DomenaViewModel
{
Tlds = db.TLDs.ToList();
};
return View(model);
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create(DomenaViewModel viewModel)
{
if (ModelState.IsValid)
{
var tld = db.TLDs.Find(model.SelectedTldId); // assuming you're using DbContext
if (tld != null)
{
// the mapping is best served in a different method, but we'll do it here for now
var newDomena = new Domena
{
TLD = tld,
Cena = tld.Cena
}
db.Domeny.Add(newDomena);
db.SaveChanges();
}
return RedirectToAction("Index");
}
viewModel.Tlds = db.TLDs.ToList();
return View(viewModel);
}
观点的相关部分:
@model DomenaViewModel
<div class="editor-field">
@Html.DropDownListFor(m => m.SelectedTldId, Model.TldItems)
</div>