Save data to SQL DB using a class in C# - c#

Sorry If I am posting this question in the wrong forum. This is my first time posting at Stackoverflow. And Also I am learning ASP.NET and C# by myself so pardon me if this elementary.
I have created a class file in ASP.NET 4.0 C# using visual studio 2010. My code is like below
namespace My.Customers
{
public class EmailMailingList
{
#region members
private string _emailList;
#endregion
#region properties
/// <summary>
/// gets or sets Customer Email for Mailing List
/// </summary>
public string EmailList
{
get { return _emailList; }
set { _emailList = value; }
}
#endregion
}
}
I have a Database table in SQL 2008 named MailingList with 2 fields namely Id and Email where Id is int with auto increment and Email Varchar(50).
I also created a Stored Procedure based on this table to enter the email address.
where I am getting confused is How can I add this info to my class file so the data can be saved to the database.
I also created a web form called Join-Mailing-List.aspx with a textbox called tbEmail and a Submit Button called Join.
What I am trying to is when someone enters the email address in the textbox I want to pass the textbox value to string EmailList in my class file and save the data to the database.
I know how to pass the textbox value to my class file. I just dont know how to save the info to the DB without using the DB code in the aspx page
Thanks and really appreciate for any advice or examples

There are a number of different ways to save information to a database using C#. Some of the more common:
ADO.NET
Linq-To-SQL
Entity Framework
You will probably need to read up on those to find the best one for you. If you want something quick and relatively easy, I would probably go with ADO.NET but others may disagree.
As far as how to include the code for the update in your class you could just add an Update() or Save() function.

There are several ways you can approach saving into database
Here is one: (simpler in my opinion)
public class EmailMailingList
{
private string _emailList;
public string EmailList
{
get { return _emailList; }
set { _emailList = value; }
}
#endregion
public void Save()
{
//Insert (this.EmailList); to database
}
}
//Use:
EmailMailingList ml = new EmailMailingList();
ml.EmailList = "blah";
ml.Save();
Some school of thought frown at that.
Another is creating a special class to do that
public class MailingListSaver
{
public static void Save(EmailMailingList ml)
{
//insert (ml.EmailList) into database
}
}
//Use:
EmailMailingList ml = new EmailMailingList();
ml.EmailList = "blah";
MailingListSaver.Save(ml);
Look into (google)
Active Record Pattern
Repository Pattern
N-tier application c#

You can simplify your class a little for clarity:
public class EmailMailingList
{
public string EmailList { get; set; }
}
Then you have MANY options for getting this info to your db. If you're just starting out, I think plain ol' ADO.Net is a get choice for getting accustomed to things. Something like:
// A method in your code-behind:
public void Save(EmailMailingList list)
{
using(var connection = new SqlConnection("your connection string"))
{
var command = connection.CreateCommand();
command.CommandText = "name of your stored procedure";
command.CommandType = CommandType.StoredProcedure;
command.Parameters.Add(new SqlParameter( ... ));
command.ExecuteNonQuery();
}
}
Of course, eventually you'll want to look into the powerful ORMs available to you in the .Net world (Entity Framework, NHibernate, LinqToSql)

I would recommend using the entity data model. It is the quickest, easiest way and it is a "best practice." You should get started bu walking through this tutorial:
http://www.asp.net/web-forms/tutorials/getting-started-with-ef/the-entity-framework-and-aspnet-getting-started-part-1
Once you have your datamodel set up using the wizard, then it is really quick and simple to save your data from a form on the code side:
dataModel.dataEntities de;
dataModel.dataTable tbl;
protected void Page_Load(object sender, EventArgs e)
{
}
protected void btnSubmit_Click(object sender, EventArgs e)
{
//Create new entity object and table object
de = new dataModel.dataEntities();
de.Connection.Open();
tbl = new dataModel.DataEntities();
tbl.Field1 = ((TextBox)tbField1).Text.ToString(); ;
tbl.Field2 = ((TextBox)tbField2).Text.ToString(); ;
//Insert the row and save the change to the table
de.AddToDataTable(tbl);
de.SaveChanges();
de.Connection.Close();
}

Related

Calling a method from a different ViewModel

I'm writing a program for managing a tool inventory and have run into a problem when I have the users mark a tool as 'fixed'.
The program should work as follows:
Using TIView, TIViewModel, TIModel:
Employee checks tool out.
Tool happens to get damaged during use.
Employee return's the tool marking it as damaged and reporting the problem.
The tool is marked as returned and locked from being check out until fixed.
Using VPRView, VPRViewModel, and VPRModel:
An inspector goes into a data grid showing all tools with problems.
The inspector corrects the problem, marks the tool as fixed, then submits the data.
The program updates the SQLite database with the inspectors ID number, their solution, marks the problem as fixed and logs the date/time of completion.
THE PROBLEM STEP:
8. The program then runs the PopulateToolInventory method from the TIViewModel to update the inventory list so that the tool is no longer locked.
Summarized:
When the inspector marks the tool as fixed the database is updated using the VPRView, VPRViewModel, and VPRModel. The method to pull the data for the tool inventory is found in the TIViewModel. How do I get the application to execute the 'PopulateToolInventory' method from the VPRViewModel after uploading the data to the database via the VPRViewModel?
Code Sample:
VPRViewModel:
public void SubmitSolution()
{
VPRModel vprm = new VPRModel();
vprm.SubmitProblemSolution(ProblemSolved, ProblemSolution, InspectorID, SelectedReport[0].ToString());
ProblemReports = vprm.RetrieveProblemReports();
InspectorID = null;
ProblemSolution = null;
ProblemSolved = false;
MessageBox.Show("Solution successfully recorded!", "Success!", MessageBoxButton.OK);
// This is where I would want to call the method from the TIViewModel to update the data grid on the TIView.
}
TIViewModel:
private DataTable _toolInventory;
public DataTable ToolInventory
{
get { return _toolInventory; }
set
{
_toolInventory = value;
NotifyOfPropertyChange(() => ToolInventory);
}
}
public void PopulateToolInventory()
{
TIModel tim = new TIModel();
ToolInventory = tim.RetrieveToolInventory();
}
ShellViewModel:
class ShellViewModel : Conductor<object>
{
public void Open_ToolInventory()
{
ActivateItem(new TIViewModel());
}
public void ViewProblemReport()
{
WindowManager wm = new WindowManager();
VPRViewModel vprvm = new VPRViewModel();
wm.ShowDialog(vprvm);
}
}
FYI: I'm using Caliburn.Micro if this helps with any solution.
Hopefully this is enough information. If not, just ask for what you need! Also, please don't eat my code alive. I'm self taught and know that I'm far from a professional developer but this is a passion of mine and I'm really enjoying it. Constructive criticism is appreciated, just please don't make me feel stupid.
Using Ed's idea in the question comments I did the following.
class ShellViewModel : Conductor<object>
{
public void Open_ToolInventory()
{
ActivateItem(new TIViewModel());
}
public void ViewProblemReport()
{
WindowManager wm = new WindowManager();
VPRViewModel vprvm = new VPRViewModel();
wm.ShowDialog(vprvm);
}
}
Was changed to:
class ShellViewModel : Conductor<object>
{
TIViewModel tivm = new TIViewModel();
VPRViewModel vprvm = new VPRViewModel();
public void OpenToolInventory()
{
ActivateItem(tivm);
}
public void ViewProblemReport()
{
WindowManager wm = new WindowManager();
wm.ShowDialog(vprvm);
tivm.PopulateToolInventory();
}
}
This runs the targeted method after the dialog is closed updating the tool inventory to reflect all the solved problems at once. You're the best, Ed!

C# - Entity type (entity) not part of model for current context error in Windows Form Application with SQL Database

I'm working on a project that involves simply filling out a string of textboxes and clicking a button that will add the values in the textboxes to their respective variables in a new instance of a class, and save this instance of the class in a database.
I created the database first of all and used Entity Frameworks to create the class from it, so I know they are linked to eachother.
The general code for my class is shown below:
public partial class AnaestheticRecord
{
public int PatientID { get; set; }
public System.DateTime Date { get; set; }
public string Owner_Name { get; set; }
//25 other attributes of class
...
//methods------------------------------------------------
//get number of instances of class (objects + 1 creates new PatientID)
private static int objects = 0;
public AnaestheticRecord()
{
++objects; //add one to count
}
~AnaestheticRecord()
{
--objects; //remove one from count
}
public static int getPatientID()
{
objects += 1; //add 1 more to create previously unused value
return objects; //return new value
}
So, when it came time to add the code to make the application function, I started by declaring new instances of the class displayed above, and of the Entities class that should allow access to the database...
public partial class Form1 : Form
{
//empty instance of class, each property takes data through console input
AnaestheticRecord aRecord = new AnaestheticRecord(); //create new instance of anaesthetic record class ready for data input
List<AnaestheticRecord> recordCollection = new List<AnaestheticRecord>(); //create list to store instances of anaesthetic records (display-record purposes)
BlueBookDBEntities db = new BlueBookDBEntities(); //create entities to run database
This all works fine, but once the series of textboxes has been filled out and the button is clicked to add this record to the datase, the following code is run and an error is produced:
private void btnSaveRecord_Click(object sender, EventArgs e)
{
//transfer and convert values from input to respective field in record
addToClass();
recordCollection.Add(aRecord); //add completed instance of class to list
db.TblAnaestheticRecords.Add(aRecord); //add completed anaesthetic record to database (ERROR)
db.SaveChanges(); //save new input to database
}
At this point, the line 'db.TblAnaestheticRecords.Add(aRecord)' throws an error stating that "Entity type AnaestheticRecord is not part of model for current context".
I'm a little stuck here, as I can't see what I've done wrong. I've done this kind of thing before using MVC where slightly more of the groundwork is done for you, but this is my first time using a database linked to a Windows Form Application.
If anyone could point out to me where I've gone wrong, and maybe point me in the right direction as to how to get past this error, I would really appreciate it.
Thanks,
Mark
In the context you need to insert also the AnaestheticRecord DbSet (all the related tables, 1 DbSet for relational table)

PetaPoco (DotNetNuke) and SQL - Adding an object with a List property or other composite object

I'm using a Data Access Layer based on PetaPoco (DotNetNuke 7.0). I've used it successfully when working with relatively simple objects but I now have to insert an object which contains at least one property which is a List of other objects.
For example:
class Person
{
public Person(){}
public string name { get; set; }
public List<Address> addresses { get; set; }
}
class Address
{
...
}
The actual object I'm working with is much more complex than the example above - there are at least four composite List objects in the object to be inserted into the repository.
What I'd like to be able to do is define the table in SQL and to be able to make a simple call to PetaPoco like this:
public static void AddOrder(Person person)
{
using (IDataContext context = DataContext.Instance())
{
var repository = context.GetRepository<Person>();
repository.Insert(person);
}
}
The background to this is that the object is passed in to a web service from a Knockout/jQuery front-end so a JSON string is converted to a data object which must then be stored on the database.
I think there are three questions really:
How do I write the SQL table which represents Person and the contained Addresses List?
How do I write the necessary PetaPoco code to insert the Person object together with any objects it contains?
Should I forget about trying to store the object on the database and just store the JSON string on the database instead?
Thanks for looking :)
I haven't installed DotNetNuke 7 yet, however I examined the source code at codeplex and I think you can do it this way:
public static void AddOrder(Person person)
{
using (IDataContext context = DataContext.Instance())
{
var repositoryPerson = context.GetRepository<Person>();
var repositoryAddrress = context.GetRepository<Address>();
context.BeginTransaction();
try
{
repositoryPerson.Insert(person);
foreach(var address in person.addresses)
{
repositoryAddress.Insert(address);
}
context.Commit();
}
catch (Exception)
{
context.RollbackTransaction();
throw;
}
}
}
I haven't tested it so I can't guarantee it works, however this seems right to me.

Custom organized data accessing via classes and constructors

struggling To achieve a solution for a basic Task:
working with more than one Sql Data table, as a source, for a WebSite application...
that's what leads me here once again... seeking for an Experienced C# .net Developers Help.
i was just trying to add some basic logic for a proper implementation,Like using
a dedicated namespace & classes, To Hold reference for All DATABASE tables,
(before i try working / learning about Entities Framework approach.)
i would like to try implement same of basic features of EF ...by my self, and that way... i will also learn how to properly work with classes.
as it is so far ... structured : with my little knowledge
a 'helper'.. namespace , say the company name is: HT technologies
so I've named the namespace HT_DbSchema ...that contains :
tables names
public sealed class HTDB_Tables
{
public const string Customers= "Customers";
public const string Times= "Times";
}
tables IDs
public sealed class HT_tblIDs
{
public const int tblCustomersID = 1, tblTimesID = 2;
}
tables Columns Lists ...(just one example)
public class HTDB_Cols
{
public class tblCustomers
{
public const string CustId = "custId",
CustName = "custName",
CellPhone = "cellPhone" .... etc'
}
}
and as all those 3 classes are serving all projects ..
there's another helper class for constructor Per Table For the Current Project
public class DBMetaDetails
{
public struct DbTable
{
public string TableName { get; set; }
public int TableID { get; set; }
}
}
so still these are all construction / helpers Classes and are separated from the project,
now for current project
What is The Appropriate way to get it done, using above Classes and constructor within a project
(i could name those templates)
what i was doing so far to implement some order is :
protected void Page_Load(object sender, EventArgs e)
{
if(!Page.IsPostBack)
{
.... some other App inits here
}
else
{
}
// this method should be the one that instanciates the DbTable struct
//and set the values of tables name and "ID"
setTablesReferences();
}
And Here's where the confusion starts :
in a day by day usage i want to try implement it in a WebSite application :
public void setTableReferences()
{
DBMetaDetails.DbTable CustMeta = new DBMetaDetails.DbTable();
DBMetaDetails.DbTable TimesMeta = new DBMetaDetails.DbTable();
}
so now i need to set CustMeta & TimesMeta details(ids & names)
the struct has a kind of a template structure a kind'a systematic technique to initialize and assign values, so it brings some decent order to my logic with it's existence .
so what is the confusing part ?
from one point of view(safety), i need those tables detailes to be readonly
so DbTable.TableID, and DbTable.TableName would not get overWriten by mistake.
having said that, there should be only one place it could be SET ... a dedicated section of the application, like setTableReferences() above,... there i might add :
CustMeta.TableID = HT_tblIDs.tblCustomersID
CustMeta.TableName = HTDB_Tables.Customers;
on the other hand, i need the information of the tables to be Accessible,
so if let's say i would like to add those DataTables into a DataSet
DataSet ALLTablesSet = new DataSet();
// assuming the SQL actions already been taken in another method previosly...
// so DataTable is already retrived from DB
//...but only as a short usage example:
AllTablesSet.Tables.Add(new DataTable(CustMeta.TableName));
My Question is What is the Correct Way to work with structs ... as in My Scenario,
So in one section of app: you would initialize - assign it with a value privately.
and from other sections of the app you could use its value (Only For Readings)
so that way, the application will not be able to access it's value for writing,
only by reading values, i think it should be trough another (Public ReadOnly) Variable.
so that variable was meant to be exposed ...and it's value could not be "harmed"
If I understand the question correctly, the way I would prevent other code from modifying it is by removing the setters on the properties. However, you still need to set them at some point, so rather than removing the setters completely, you can just make them private. For example:
public string TableName { get; private set; }
If you do this, the only place you can set this data is within the struct itself, so you would need to create a constructor that took the initial values you wanted. So something like:
public struct DbTable
{
public DbTable(string tableName, int tableId)
{
this.TableName = tableName;
this.TableID = tableId;
}
public string TableName { get; private set; }
public int TableID { get; private set; }
}

Modifying connection string of an ASP.NET GridView -> BLL -> DAL at runtime

I am constructing a page to display a GridView of client data with pagination. My aspx page has a GridView whos DataSourceID is set to an ObjectDataSource. The ObjectDataSource is bound to a a BLL which in turn accesses the data through a DAL. I have the whole thing up and running while pointing to a static database. However, each client's data is stored in its own database. The next step is to modify the ConnectionString of the DAL depending on client login.
I have configured the DAL TableAdapter with the option ConnectionModifier set to 'Public'. My BLL can modify the connection string of the DAL, however I do not know how to pass to the BLL the client database name.
public class PDFDocumentsBLL {
private PDFTableAdapter _pdfdocumentsadapter = null;
protected PDFTableAdapter Adapter {
get {
if ( _pdfdocumentsadapter == null ) {
_pdfdocumentsadapter = new PDFTableAdapter();
_pdfdocumentsadapter.Connection = new System.Data.SqlClient.SqlConnection(
ConfigurationManager.ConnectionStrings["template"].ConnectionString.Replace( "TEMPLATE", "TESTCLIENT" )
);
}
return _pdfdocumentsadapter;
}
}
...
}
I would like to replace the string "TESTCLIENT" in the above code with a variable, but I am at a loss on how to pass this information to the BLL.
You may create some kind of database name provider that will return database name based on username, like
public class DataBaseNameProvider
{
public string GetDataBaseName()
{
var userName = Membership.GetUser().UserName;
return GetDatabaseNameByUserName(userName);
}
}
And call that class from your BLL.
If you don't like idea to use ASP.NET stuff in your BLL because you don't want to add additional dependency, you still can create a wrapper around your BLL that will be Membership aware and will create your BLL passing username there.
If you are using Windows Authentication, then you can simply use
ConfigurationManager.ConnectionStrings[WindowsIdentity.GetCurrent().Name]
And might be good practice to retrieve the whole connection string for each user, it makes it more flexible, so you could use a completely different type of database if needed.
What I ended up doing is adding a PDFDB property to my BLL:
public class PDFDocumentsBLL {
private PDFTableAdapter _pdfdocumentsadapter = null;
public string PDFDB = "PDF_TEMPLATE";
protected PDFTableAdapter Adapter {
get {
if ( _pdfdocumentsadapter == null ) {
_pdfdocumentsadapter = new PDFTableAdapter();
_pdfdocumentsadapter.Connection = new System.Data.SqlClient.SqlConnection(
ConfigurationManager.ConnectionStrings["pdf"].ConnectionString.Replace( "PDF_TEMPLATE", PDFDB )
);
}
return _pdfdocumentsadapter;
}
}
}
I then modified the GetBy/FillBy functions to take the DB as an additional parameter, and configured the ObjectDataSource to pass that value in from the Session variable.

Categories

Resources