Diskuze: ASP.NET MVC a DATABÁZE
V předchozím kvízu, Test znalostí C# .NET online, jsme si ověřili nabyté zkušenosti z kurzu.
Člen
Zobrazeno 20 zpráv z 20.
//= Settings::TRACKING_CODE_B ?> //= Settings::TRACKING_CODE ?>
V předchozím kvízu, Test znalostí C# .NET online, jsme si ověřili nabyté zkušenosti z kurzu.
Hodně zjednodušeně se to dá takhle udělat. Sčítat a odčítat se
nebude v SQL, ale při ukládání do DB, tzn, že záznam se uloží už
sečtený/odečtený. V modelu budeš mít záznam o aktuálním zůstatku,
provedeš operaci a uložíš nový záznam s vypočteným zůstatkem.
Ale jak říkám, je to hodně zjednodušený pohled na rozpočet, asi bych ho
řešil trošku rozvinutěji s ohledem na možnosti budoucího rozvíjení
projektu...
Ja jsem taky tento problem nastinil zjednodušeně, jen jsem potreboval vedet od jakehokoli profika nazor, zda je toto spravna cesta ohledne tabulek. Taky uz me napadlo to udelat v modelu a ulozit to do databaze jako hotove, ale nejak mi to neslo
V tom případě ale musím do modelu dostat data z tabulky, nahrát do proměnné, provést výpočet a pak výsledek poslat zpět na nový řádek do databáze. Je zde tento podobný postup někde vysvětlen? Já nevím, jak konkrétně data z tabulky dostat do C# třídy - modelu.
Nejlépe přes ViewModel. Tady je na ASP.NET MVC pěkný tutoriál a poměrně dost materiálu v diskusích...
Jedu podle tohoto tutoriálu, jak komunikovat s databází, ale v kódu mám stále něco červeně podtrženo a nevím proč. Napadá mě, že nepracuji s konzolovou aplikací, ale nevím jak to upravit, aby to běželo. Poradíš mi?
using System;
using System.Collections.Generic;
using System.Data.SqlClient;
using System.Data;
using System.Linq;
using System.Web;
using System.Threading.Tasks;
namespace RodinnyRozpocet.Models
{
public class Money
{
SqlConnectionStringBuilder csb = new SqlConnectionStringBuilder();
csb.DataSource = @"localhost\SQLEXPRESS";
csb.InitialCatalog = "mojedatabaze";
csb.IntegratedSecurity = true;
string pripojovaciRetezec = csb.ConnectionString;
}
}
Od části csb.DataSource je vše podtrženo. Píše mi to, že v tomto kontextu nic neexistuje.
Být tebou, tak jedu podle tutoriálu pro ASP.NET MVC a ne podle "C# databáze", zjistíš, že komunikace je trochu jiná, ale v podstatě ve finále jednodušší... Použití EF je pro ASP.NET MVC ideální. I tam se lze k DB připojit klasickými SQL dotazy, ale ne přes "SqlConnectionStringBuilder", nýbrž přes normální jméno ConnectionStringu, který je ve web.config.
Přes EF jsem si vygeneroval kontroler a pohledy (create atd.). Chtěl jsem se inspirovat kódem v kontroleru pro zobrazení v souboru Details. Je tam uvedeno toto:
public ActionResult Details(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
FamilyMoney familyMoney = db.FamilyMoneys.Find(id);
if (familyMoney == null)
{
return HttpNotFound();
}
return View(familyMoney);
}
Upravil jsem si to v pohledu tak, aby mi to zobrazovalo jeden sloupec z tabulky, ale je třeba zadat konkrétní id, viz. toto:
public ActionResult Details(int? id)
Zkoušel jsem třeba, aby to zobrazovalo poslední známé Id:
FamilyMoney familyMoney = db.FamilyMoneys.Max(id);
Stále mi to vyhazuje chyby nebo když už to sepíšu dobře, tak to vyhodí chybu, že nelze kombinovat LINQ atd.
Upřímně, vůbec nevím, jak zde komunikovat s již vytvořenou databází. Přes SQL zhruba vím jak, ale netuším, jak ten SQL příkaz sepsat v kontroleru. Pokud tak nějak víš, o co mi jde, mohl by jsi mě nasměrovat přesněji jak na to, případně který konkrétní tutoriál mi tohle vysvětlí? Většinu co jsem tu projel, nijak mi to nepomohlo. Možná to jen nechápu.
Díky za Tvůj čas.
Musíš si to id z toho vytáhnout, tady máš "FamilyMoney"
FamilyMoney familyMoney = db.FamilyMoneys.Find(id);
tak z něj jen to id vyber
return View(familyMoney.id);
Detail záznamu asi taháš z nějakého výpisu, takže to id tam pošleš tím stisknutím tlačítka nebo toho odkazu detail
Asi mi nerozumíš, ale problém je v tom, že nevím,** jak konkrétně to ID vzít z tabulky**. To co jsi mi poradil zřejmě nefunguje nebo to nechápu já.
Prostě mám tabulku, kde první sloupec představuje ID. Jakým způsobem je možný z té tabulky dostat hodnotu s největším ID nebo poslední přidaný řádek a jeho ID?
Jak by vypadal zápis? Já si fakt nevím rady, nerozumím tomu.
Jak vypadá ten výpis nebo seznam položek, z kterých pak chceš detail?
Složka Models - FamilyMoney.cs
public class FamilyMoney
{
public int Id { get; set; }
public DateTime Date { get; set; }
public double Balance { get; set; }
public double Saving { get; set; }
public double Reserve { get; set; }
public double AddIncome { get; set; }
public double AddExpense { get; set; }
public double AddSave { get; set; }
public double AddReserve { get; set; }
public double TakeSave { get; set; }
public double TakeReserve { get; set; }
public string Note { get; set; }
}
Složka Controllers - FamilyMoneysController.cs
public class FamilyMoneysController : Controller
{
private ApplicationDbContext db = new ApplicationDbContext();
// GET: FamilyMoneys
public ActionResult Index()
{
return View(db.FamilyMoneys.ToList());
}
// GET: FamilyMoneys/Details/5
public ActionResult Details(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
FamilyMoney familyMoney = db.FamilyMoneys.Find(id);
if (familyMoney == null)
{
return HttpNotFound();
}
return View(familyMoney);
}
// GET: FamilyMoneys/Create
public ActionResult Create()
{
return View();
}
// POST: FamilyMoneys/Create
// Chcete-li zajistit ochranu před útoky typu OVERPOST, povolte konkrétní vlastnosti, k nimž chcete vytvořit vazbu.
// Další informace viz https://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Create([Bind(Include = "Id,Date,Balance,Saving,Reserve,AddIncome,AddExpense,AddSave,AddReserve,TakeSave,TakeReserve,Note")] FamilyMoney familyMoney)
{
if (ModelState.IsValid)
{
db.FamilyMoneys.Add(familyMoney);
db.SaveChanges();
return RedirectToAction("Index");
}
return View(familyMoney);
}
// GET: FamilyMoneys/Edit/5
public ActionResult Edit(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
FamilyMoney familyMoney = db.FamilyMoneys.Find(id);
if (familyMoney == null)
{
return HttpNotFound();
}
return View(familyMoney);
}
// POST: FamilyMoneys/Edit/5
// Chcete-li zajistit ochranu před útoky typu OVERPOST, povolte konkrétní vlastnosti, k nimž chcete vytvořit vazbu.
// Další informace viz https://go.microsoft.com/fwlink/?LinkId=317598.
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit([Bind(Include = "Id,Date,Balance,Saving,Reserve,AddIncome,AddExpense,AddSave,AddReserve,TakeSave,TakeReserve,Note")] FamilyMoney familyMoney)
{
if (ModelState.IsValid)
{
db.Entry(familyMoney).State = EntityState.Modified;
db.SaveChanges();
return RedirectToAction("Index");
}
return View(familyMoney);
}
// GET: FamilyMoneys/Delete/5
public ActionResult Delete(int? id)
{
if (id == null)
{
return new HttpStatusCodeResult(HttpStatusCode.BadRequest);
}
FamilyMoney familyMoney = db.FamilyMoneys.Find(id);
if (familyMoney == null)
{
return HttpNotFound();
}
return View(familyMoney);
}
// POST: FamilyMoneys/Delete/5
[HttpPost, ActionName("Delete")]
[ValidateAntiForgeryToken]
public ActionResult DeleteConfirmed(int id)
{
FamilyMoney familyMoney = db.FamilyMoneys.Find(id);
db.FamilyMoneys.Remove(familyMoney);
db.SaveChanges();
return RedirectToAction("Index");
}
protected override void Dispose(bool disposing)
{
if (disposing)
{
db.Dispose();
}
base.Dispose(disposing);
}
// GET: Balance
public ActionResult Balance()
{
FamilyMoney familyMoney = db.FamilyMoneys.Find(id);
return View(familyMoney.id);
}
}
Složka Views - Balance.cshtml
@model RodinnyRozpocet.Models.FamilyMoney
@{
ViewBag.Title = "Aktuální zůstatek";
}
<h2>Details</h2>
<div>
<h4>FamilyMoney</h4>
<hr />
<dl class="dl-horizontal">
<dt>
@Html.DisplayNameFor(model => model.Date)
</dt>
<dd>
@Html.DisplayFor(model => model.Date)
</dd>
<dt>
@Html.DisplayNameFor(model => model.Balance)
</dt>
<dd>
@Html.DisplayFor(model => model.Balance)
</dd>
</dl>
</div>
<p>
@Html.ActionLink("Edit", "Edit", new { id = Model.Id }) |
@Html.ActionLink("Back to List", "Index")
</p>
Jen dodám, že pohled Balance.cshtml by měl vypsat poslední zůstatek, když to bude na v tabulce na řádku 8 - tak bere z řádku s ID 8 atd....
Mám pocit, že
db.FamilyMoneys.Find(id);
Ti vráti stále null, lebo keby si chcel využiť Find, tak by si potreboval dať ako argument celý objekt a nie len Id, takže to skús skôr takto
db.FamilyMoneys.FirstOrDefault(m => m.Id == id);
Vráti ti to prvý prvok, ktorý splní podmienku, ale keďže Id je unikátne netreba sa báť, že by to vrátilo niečo nechcené.
var result = db.FamilyMoneys.OrderByDescending(a => a.Id).FirstOrDefault();
Tohle je přesně to, co mi pomohlo, velký dík. Každopádně jelikož v tom trochu plavu, mohl bych Tě poprosit, jestli by jsi mi, prosím, vysvětlil, co jaká část kódu přesně dělá? Případně jestli to tu někdo vysvětloval nebo tady někde na ITNetwork článek. To se týká LINQ?
Kluci díky za Váš čas!
no je to celkom jednoduché db.FamilyMoneys je tvoj povedzme laicky pole všetkých výsledkov, OrderByDescending(a => a.Id) zoradí tento list zostupne podľa Id a FirstOrDefault vráti prvý prvok v tomto poli. A áno je to LINQ a pár článkov na kolekcie a LINQ samotný je tu Kolekce a LINQ
A z toho Balance.cshtml toto
@Html.ActionLink("Edit", "Edit", new { id = Model.Id })
je právě ten odkaz, který ti pošle "to" ID zvoleného záznamu do detailu, nebo do editu, podle toho co v tom odkazu bude - v tomto případě to bude do editu...
A ty samé odkazy máš ve "výpisu" - seznamu řádků...
Paráda, už to dělá to co potřebuji. Už vím jak komunikovat s databází, díky všem.
Zobrazeno 20 zpráv z 20.