Válí se ti projekty v šuplíku? Dostaň je mezi lidi a získej cool tričko a body na profi IT kurzy v soutěži ITnetwork summer 2017!
Přidej si svou IT školu do profilu a najdi spolužáky zde na síti :)
Avatar
Jarda Pácha
Člen
Avatar
Jarda Pácha:16. května 14:53

Zdravím,

zkouším si naprogramovat webovou aplikaci, která bude umět spravovat rodinný rozpočet financí. Akorát mi tak nějak utekla myšlenka, jak vůbec uchovávat data. Tak mě napadlo jít přes SQL a tabulky - tam jsem si vytvořil "Id", "Aktuální zůstatek" a "Příjem". Když mám příjem 100, sloupec s aktuálním zůstatkem bude též 100 (Id 1). Když budu mít další příjem, zůstatek už bude 200 po vykonání příkazu (Id 2). Chci se zeptat na dvě věci. Jdu na to správným směrem co se týče myšlenky? Pokud ne, jak by jste to udělali? A pokud na to jdu správně, jak můžu sčítat a odčítat v SQL. Jestli jsem to někde přehlédl, tak se omlouvám. :)) Přeji všem hezké odpoledne.

Odpovědět 16. května 14:53
Všechno co se děje, je výsledkem našich myšlenek.
Avatar
Odpovídá na Jarda Pácha
Michal Štěpánek:16. května 15:25

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...

Akceptované řešení
+20 Zkušeností
+1 bodů
Řešení problému
Nahoru Odpovědět  +1 16. května 15:25
Nikdy neříkej nahlas, že to nejde. Vždycky se totiž najde blbec, který to neví a udělá to...
Avatar
Jarda Pácha
Člen
Avatar
Jarda Pácha:16. května 15:38

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 :D :)

Nahoru Odpovědět 16. května 15:38
Všechno co se děje, je výsledkem našich myšlenek.
Avatar
Jarda Pácha
Člen
Avatar
Jarda Pácha:16. května 20:04

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.

Nahoru Odpovědět 16. května 20:04
Všechno co se děje, je výsledkem našich myšlenek.
Avatar
Odpovídá na Jarda Pácha
Michal Štěpánek:16. května 22:32

Nejlépe přes ViewModel. Tady je na ASP.NET MVC pěkný tutoriál a poměrně dost materiálu v diskusích...

Nahoru Odpovědět 16. května 22:32
Nikdy neříkej nahlas, že to nejde. Vždycky se totiž najde blbec, který to neví a udělá to...
Avatar
Jarda Pácha
Člen
Avatar
Odpovídá na Michal Štěpánek
Jarda Pácha:17. května 12:41

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.

Nahoru Odpovědět 17. května 12:41
Všechno co se děje, je výsledkem našich myšlenek.
Avatar
Odpovídá na Jarda Pácha
Michal Štěpánek:17. května 12:55

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 "SqlConnection­StringBuilder", nýbrž přes normální jméno ConnectionStringu, který je ve web.config.

Nahoru Odpovědět 17. května 12:55
Nikdy neříkej nahlas, že to nejde. Vždycky se totiž najde blbec, který to neví a udělá to...
Avatar
Jarda Pácha
Člen
Avatar
Odpovídá na Michal Štěpánek
Jarda Pácha:18. května 13:01

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. :)

Nahoru Odpovědět 18. května 13:01
Všechno co se děje, je výsledkem našich myšlenek.
Avatar
Odpovídá na Jarda Pácha
Michal Štěpánek:18. května 13:53

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

Editováno 18. května 13:55
Nahoru Odpovědět 18. května 13:53
Nikdy neříkej nahlas, že to nejde. Vždycky se totiž najde blbec, který to neví a udělá to...
Avatar
Jarda Pácha
Člen
Avatar
Odpovídá na Michal Štěpánek
Jarda Pácha:18. května 15:35

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.

Nahoru Odpovědět 18. května 15:35
Všechno co se děje, je výsledkem našich myšlenek.
Avatar
Odpovídá na Jarda Pácha
Michal Štěpánek:18. května 17:35

Jak vypadá ten výpis nebo seznam položek, z kterých pak chceš detail?

Nahoru Odpovědět 18. května 17:35
Nikdy neříkej nahlas, že to nejde. Vždycky se totiž najde blbec, který to neví a udělá to...
Avatar
xpoproci
Člen
Avatar
xpoproci:18. května 17:48

Ak chceš vybrať záznam s najvyšším Id tak si to stačí podľa toho Id zoradiť či už vzostupne alebo zostupne, to je na tebe.

var result = db.FamilyMoneys.OrderByDescending(a => a.Id).FirstOrDefault();
Nahoru Odpovědět  +1 18. května 17:48
Žiaden človek nedokáže dať toľko lásky človeku, ako dokáže dať len človek človeku. -Kapitán
Avatar
Jarda Pácha
Člen
Avatar
Jarda Pácha:18. května 17:49

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 - FamilyMoneysCon­troller.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....

Nahoru Odpovědět 18. května 17:49
Všechno co se děje, je výsledkem našich myšlenek.
Avatar
Jarda Pácha
Člen
Avatar
Odpovídá na xpoproci
Jarda Pácha:18. května 17:50

OK, kouknu a zkusím, děkuji. :)

Nahoru Odpovědět 18. května 17:50
Všechno co se děje, je výsledkem našich myšlenek.
Avatar
xpoproci
Člen
Avatar
xpoproci:18. května 18:24

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é.

Editováno 18. května 18:24
Nahoru Odpovědět 18. května 18:24
Žiaden človek nedokáže dať toľko lásky človeku, ako dokáže dať len človek človeku. -Kapitán
Avatar
Jarda Pácha
Člen
Avatar
Odpovídá na xpoproci
Jarda Pácha:18. května 18:47
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! :)

Nahoru Odpovědět 18. května 18:47
Všechno co se děje, je výsledkem našich myšlenek.
Avatar
xpoproci
Člen
Avatar
Odpovídá na Jarda Pácha
xpoproci:18. května 22:24

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

Nahoru Odpovědět  +1 18. května 22:24
Žiaden človek nedokáže dať toľko lásky človeku, ako dokáže dať len človek človeku. -Kapitán
Avatar
Odpovídá na Jarda Pácha
Michal Štěpánek:19. května 7:46

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...

Nahoru Odpovědět 19. května 7:46
Nikdy neříkej nahlas, že to nejde. Vždycky se totiž najde blbec, který to neví a udělá to...
Avatar
Odpovídá na Jarda Pácha
Michal Štěpánek:19. května 7:50

A ty samé odkazy máš ve "výpisu" - seznamu řádků...

Nahoru Odpovědět 19. května 7:50
Nikdy neříkej nahlas, že to nejde. Vždycky se totiž najde blbec, který to neví a udělá to...
Avatar
Jarda Pácha
Člen
Avatar
Jarda Pácha:20. května 11:26

Paráda, už to dělá to co potřebuji. :-) Už vím jak komunikovat s databází, díky všem. :-)

Nahoru Odpovědět 20. května 11:26
Všechno co se děje, je výsledkem našich myšlenek.
Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zobrazeno 20 zpráv z 20.