IT rekvalifikace s garancí práce. Seniorní programátoři vydělávají až 160 000 Kč/měsíc a rekvalifikace je prvním krokem. Zjisti, jak na to!
Hledáme nové posily do ITnetwork týmu. Podívej se na volné pozice a přidej se do nejagilnější firmy na trhu - Více informací.
Avatar
Jarda Pácha
Člen
Avatar
Jarda Pácha:16.5.2017 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.5.2017 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.5.2017 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í
+2,50 Kč
Řešení problému
Nahoru Odpovědět
16.5.2017 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.5.2017 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.5.2017 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.5.2017 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.5.2017 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.5.2017 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.5.2017 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.5.2017 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.5.2017 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.5.2017 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.5.2017 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.5.2017 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.5.2017 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.5.2017 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.5.2017 13:55
Nahoru Odpovědět
18.5.2017 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.5.2017 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.5.2017 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.5.2017 17:35

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

Nahoru Odpovědět
18.5.2017 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.5.2017 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
18.5.2017 17:48
Motto
Avatar
Jarda Pácha
Člen
Avatar
Jarda Pácha:18.5.2017 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.5.2017 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.5.2017 17:50

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

Nahoru Odpovědět
18.5.2017 17:50
Všechno co se děje, je výsledkem našich myšlenek.
Avatar
xpoproci
Člen
Avatar
xpoproci:18.5.2017 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.5.2017 18:24
Nahoru Odpovědět
18.5.2017 18:24
Motto
Avatar
Jarda Pácha
Člen
Avatar
Odpovídá na xpoproci
Jarda Pácha:18.5.2017 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.5.2017 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.5.2017 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
18.5.2017 22:24
Motto
Avatar
Odpovídá na Jarda Pácha
Michal Štěpánek:19.5.2017 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.5.2017 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.5.2017 7:50

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

Nahoru Odpovědět
19.5.2017 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.5.2017 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.5.2017 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.