Any suggestions for better function to get data from DataBase - c#

To get my data(users and books) from Firebird base I am using the following methods:
public static Dictionary<string, Users> getUsersFromDB()
{
Dictionary<string, Users> users_list = new Dictionary<string, Users>();
string reqestCommand = "SELECT id, user_type, user_nick, user_pass, user_fname, user_lname, user_identify, e_mail,address, registered FROM USERS";
string connectionString = connectionPath();
using (FbConnection fbDB = new FbConnection(connectionString))
{
fbDB.Open();
FbCommand reqest = new FbCommand(reqestCommand, fbDB);
using (FbDataReader reader = reqest.ExecuteReader())
{
while (reader.Read())
{
string key;
Users user = new Users();
user.ID = reader.GetInt32(0);
user.type = reader.GetString(1).Trim();
key = reader.GetString(2).Trim();
user.nick = key;
user.password = reader.GetString(3).Trim();
user.fName = reader.GetString(4).Trim();
user.lName = reader.GetString(5).Trim();
user.identify = reader.GetString(6).Trim();
user.email = reader.GetString(7).Trim();
user.address = reader.GetString(8).Trim();
user.registerDate = reader.GetString(9).Trim();
user.localOrInDb = "inDatabase";
users_list.Add(key, user);
}
}
fbDB.Close();
}
return users_list;
}
public static Dictionary<Guid, Books> getBooksFromDB()
{
Dictionary<Guid, Books> books_list = new Dictionary<Guid, Books>();
string reqestCommand = "SELECT book_id, book_title, book_author, book_genre, book_language, book_rel_date, book_page_number, book_available_amount, book_type FROM BOOKS";
string connectionString = connectionPath();
using (FbConnection fbDB = new FbConnection(connectionString))
{
fbDB.Open();
FbCommand reqest = new FbCommand(reqestCommand, fbDB);
using (FbDataReader reader = reqest.ExecuteReader())
{
while (reader.Read())
{
Guid key;
Books book = new Books();
Guid theGuid = new Guid(reader.GetString(0).Trim());
key = book.ID = theGuid;
book.title = reader.GetString(1).Trim();
book.author = reader.GetString(2).Trim();
book.genre = reader.GetString(3).Trim();
book.language = reader.GetString(4).Trim();
book.rel_date = reader.GetString(5).Trim();
book.page_number = reader.GetInt32(6);
book.amount = reader.GetInt32(7);
book.type = reader.GetString(8).Trim();
book.localOrInDb = "inDatabase";
books_list.Add(key, book);
}
}
fbDB.Close();
}
return books_list;
}
How can we see, they are almost same, so question:
Is it possible to make from them one function? Or would it be better to leave them separate?

You can pass a parameter that makes an instance of your target class from Reader:
public static Dictionary<K,T> GetFromDb<K,T>(Func<Reader,KeyValuePair<K,T> maker) {
var res = new Dictionary<K,T>();
// ... your code ...
while (reader.Read()) {
res.Add(maker(reader));
}
return res;
}
Now you can call your GetFromDb like this:
var users = GetFromDb<string,User>(reader => {
string key;
Users user = new Users();
user.ID = reader.GetInt32(0);
user.type = reader.GetString(1).Trim();
key = reader.GetString(2).Trim();
user.nick = key;
user.password = reader.GetString(3).Trim();
user.fName = reader.GetString(4).Trim();
user.lName = reader.GetString(5).Trim();
user.identify = reader.GetString(6).Trim();
user.email = reader.GetString(7).Trim();
user.address = reader.GetString(8).Trim();
user.registerDate = reader.GetString(9).Trim();
user.localOrInDb = "inDatabase";
return new KeyValuePair<string,User>(key, user);
});

Check this post
https://stackoverflow.com/a/1464929/988830
You can abstract the reader using extension method.
However you have to create the FBconnection everytime. If you try to put it in a function and access it from another one then you will get exception that reader is closed.
using uses IDisposible http://msdn.microsoft.com/en-us/library/system.idisposable.aspx
which closes the connection.
Another option
Start using orm like Entity framework or NHibernate which will map the table with your object.

Related

How to insert multiple items in Quickbook Invoice

I need to insert a new invoice for a particular customer , I can able to insert , but i don't have any idea about how to insert multiple items in invoice. How to use the property Items and ItemsElementName to insert multiple items.
If my question is unclear please let me know. I have attached the snapshot and code for reference.
Code:
protected void btnsendInvoiceDetails_Click(object sender, EventArgs e)
{
string accessToken = "lvprdRM1HLr6o11Bnip2fGizlXWbFfADnS1Btvm2L4VPOTRI";
string appToken = "297db54bb5526b494adb86fb2a41063192cd";
string accessTokenSecret = "JfSTrprW83JTXrSVHD3uf7th23gP0SOzBQcn4Nrt";
string consumerKey = "qyprdKLN5YHpCPSlWQZTiKVc28dywR";
string consumerSecret = "JPMNB37YnCPGU9m9vuXkF2M71lbDb7blhcLB7HeF";
string companyID = "813162085";
OAuthRequestValidator oauthValidator = new OAuthRequestValidator(accessToken, accessTokenSecret, consumerKey, consumerSecret);
ServiceContext context = new ServiceContext(oauthValidator,appToken,companyID, IntuitServicesType.QBO);
DataServices service = new DataServices(context);
InvoiceHeader a = new InvoiceHeader();
a.CustomerName = "Antivirus Norton Security";
a.CustomerId = new IdType { idDomain = idDomainEnum.QBO, Value = "6" };
a.TotalAmt = 157.00m;
a.SubTotalAmt = 37.00m;
a.ShipMethodName = "Gmail";
a.ShipMethodId = new IdType { idDomain = idDomainEnum.QBO, Value = "41" };
a.DocNumber = "1040";
a.DueDateSpecified = true;
// a.Item = 10.00m;
//a.ItemElementName = ItemChoiceType2.DiscountAmt;
DateTime dt = Convert.ToDateTime("08/07/2013");
a.DueDate = dt;
InvoiceLine mnm = new InvoiceLine();
mnm.Desc = "Antivirus Norton Security The Best Security ";
mnm.Id = new IdType { idDomain = idDomainEnum.QBO, Value = "25" };
mnm.Amount = 65.00m;
mnm.AmountSpecified = true;
// mnm.Items = "Europe";
//mnm.ItemsElementName = "Zebronic";
InvoiceLine[] invline = new InvoiceLine[] { mnm };
var invoices = new Intuit.Ipp.Data.Qbo.Invoice();
invoices.Header = a;
invoices.Line = invline;
var addedInvoice = service.Add(invoices);
var qboInvoices = service.FindAll(invoices, 1,10);
foreach (var qboinv in qboInvoices)
{
string id = Convert.ToString(qboinv.Id.Value);
}
GridView1.DataSource = invoices;
GridView1.DataBind();
}
Image:
Try this:
InvoiceLine i = new InvoiceLine();
i.ItemsElementName = new ItemsChoiceType2[1];
i.ItemsElementName[0] = ItemsChoiceType2.ItemId;
i.Items = new Intuit.Ipp.Data.Qbd.IdType[1];
i.Items[0] = new Intuit.Ipp.Data.Qbd.IdType() { idDomain = Intuit.Ipp.Data.Qbd.idDomainEnum.QBO, Value = "6" };

Adding and Editing using same connection in EF4

I'm using EF4 to look up a item in the database, to determine if it needs to be inserted or edited like so:
List<Campground> CampgroundEntities = new List<Campground>();
using (MiscEntities pd = new MiscEntities())
{
Campground kc = pd.Campground.FirstOrDefault(i => i.Name == name);
if (kc != null)
{
kc.StreetAddress = streetAddress;
kc.City = city;
kc.State = state;
kc.Zip = zip;
kc.URL = campgroundUrl;
kc.UpdatedDT = DateTime.Now;
CampgroundEntities.Add(kc);
}
else
{
kc = new Campground();
kc.Name = name;
kc.StreetAddress = streetAddress;
kc.City = city;
kc.State = state;
kc.Zip = zip;
kc.URL = campgroundUrl;
kc.AddedDateTime = DateTime.Now;
CampgroundEntities.Add(kc);
}
}
I'm adding my entities to a list, then after that, I want to commit those changes to the database:
using (MiscEntities pd = new MiscEntities())
{
foreach (var item in CampgroundEntities)
{
pd.Campground.AddObject(item);
}
pd.SaveChanges();
}
Now obviously that doesn't work, but if possible, I'd like to use that connection to handle both inserting and updating. Can it be done?
using (MiscEntities pd = new MiscEntities())
{
Campground kc = pd.Campground.FirstOrDefault(i => i.Name == name);
if (kc == null)
{
kc = new Campground();
pd.Campground.Add(kc);
}
kc.StreetAddress = streetAddress;
kc.City = city;
kc.State = state;
kc.Zip = zip;
kc.URL = campgroundUrl;
kc.UpdatedDT = DateTime.Now;
CampgroundEntities.Add(kc);
}

Inserting data into different tables at the same time with Linq-to-SQL

I have Linq-to-SQL code here which submits data into the database in their respective table,
PatientInformation and ResponsibleParty:
public void addPatientInformation() {
using(DbClassesDataContext myDb = new DbClassesDataContext(dbPath)){
PatientInfo patientInfo = new PatientInfo();
patientInfo.Phy_ID = physcianID;
patientInfo.Pat_First_Name = txtFirstName.Text;
patientInfo.Pat_Middle_Name = txtMiddleName.Text;
patientInfo.Pat_Last_Name = txtLastName.Text;
patientInfo.Pat_Gender = cmbGender.Text;
patientInfo.Pat_Marital_Status = cmbMaritalStatus.Text;
patientInfo.Pat_Date_Of_Birth = dtpDOB.Value;
patientInfo.Pat_Home_Add = txtHomeAdd.Text;
patientInfo.Pat_Home_Num = txtPhone.Text;
patientInfo.Pat_Work_Add = txtWorkAdd.Text;
patientInfo.Pat_Work_Num = txtWorkPhone.Text;
patientInfo.Pat_Prim_Physician = txtPrimPhysician.Text;
patientInfo.Pat_Ref_Physician = txtRefePhysician.Text;
myDb.PatientInfos.InsertOnSubmit(patientInfo);
myDb.SubmitChanges();
}
}
public void addResponsiblePartyInformation() {
using(DbClassesDataContext myDb = new DbClassesDataContext(dbPath)){
ResponsibleParty responsibleParty = new ResponsibleParty();
responsibleParty.Res_First_Name = txtResFirstName.Text;
responsibleParty.Res_Middle_Init = txtResMiddleName.Text;
responsibleParty.Res_Last_Name = txtResLName.Text;
responsibleParty.Res_Gender = cmbResGender.Text;
responsibleParty.Res_Marital_Status = cmbResMaritalStatus.Text;
responsibleParty.Res_Date_Of_Birth = dtpResDOB.Value;
responsibleParty.Res_Home_Add = txtResHomeAdd.Text;
responsibleParty.Res_Home_Num = txtResPhone.Text;
responsibleParty.Res_Work_Add = txtResWorkAdd.Text;
responsibleParty.Res_Work_Num = txtResWorkPhone.Text;
myDb.ResponsibleParties.InsertOnSubmit(responsibleParty);
myDb.SubmitChanges();
}
And a method named
public void submitInformationToDatabase() {
addPatientInformation();
addResponsiblePartyInformation();
MessageBox.Show("Patient Demographics Has Been added.");
}
Is there a way I could submit them at once?
Two options:
pass the data-context in and don't call SubmitChanges() every time (maybe make it optional)
use a transaction
For the second, TransactionScope could be used to do this without having to change the two methods:
using(var tran = new TransactionScope()) {
method1(...);
method2(...);
tran.Complete();
}
Or with the other approach (after adding an optional parameter):
using(var ctx = new SomeDataContext(...)) {
method1(ctx, ..., submitChanges: false);
method2(ctx, ..., submitChanges: false);
ctx.SubmitChanges();
}
If you can refactor your code to something resembling the example below, then both records will be inserted in the same submit.
using(DbClassesDataContext myDb = new DbClassesDataContext(dbPath)){
myDb.PatientInfos.InsertOnSubmit(patientInfo);
myDb.ResponsibleParties.InsertOnSubmit(responsibleParty);
myDb.SubmitChanges();
}
Pass connection as parameter with both method and use System.Transaction:
public void submitInformationToDatabase() {
using (System.Transactions.TransactionScope tr = new System.Transactions.TransactionScope())
{
System.Data.SqlClient.SqlConnection con = new System.Data.SqlClient.SqlConnection(dbPath);
con.Open();
addPatientInformation(con);
addResponsiblePartyInformation(con);
tr.Complete();
}
MessageBox.Show("Patient Demographics Has Been added.");
}

How to Create a campaign in MailChimp using ASP.Net

I need to create and send immediately campaigns in MailChimp.com. I used C# wrapper Percepective MCAPI.dll for this purpose.
from the MailChimp API, Its clear that we cannot lists but can create campaigns. I tried code but the campaignID is retured null; no exception thrown atleast. I did set the campaigntype to Auto.
here is my code snippet:
try
{
string apiKey = "api-us2"; // API KEY is valid
string emailAddress = "ravinderpal.singh#abc.net";
listsForEmailInput lstForEmailInput = new listsForEmailInput(apiKey, emailAddress);
listsForEmail cmd = new listsForEmail(lstForEmailInput);
listsForEmailOutput lstEmailOutPut = cmd.Execute();
List lstResults = lstEmailOutPut.result;
string listID = lstResults[0]; // Got Precraeted List ID( Valid Confirmed )
Console.WriteLine("\n" + listID);
// compaign Create
campaignCreateOptions campaignCreateOpt = new campaignCreateOptions();
campaignCreateOpt.list_id = listID;
campaignCreateOpt.subject = " New Campaign from dev_Anil";
campaignCreateOpt.from_email = "anil.k#abc.net";
campaignCreateOpt.from_name = "anil";
Dictionary content = new Dictionary();
content.Add("html", "Helloaasdsa");
content.Add("text", "Hi all !! this is dev_anil");
content.Add("url", "");
content.Add("archive", "");
campaignSegmentOptions csOptions = new campaignSegmentOptions();
csOptions.match = "any"; // Could not set Condition -- need help for this
// Need to set a Dictionary typeOptions because null is not supported
Dictionary typeOptions = new Dictionary();
campaignCreateParms campaignCreateParms = new campaignCreateParms(apiKey, EnumValues.campaign_type.auto, campaignCreateOpt, content, csOptions, typeOptions);
campaignCreateInput campaignCreateInput = new campaignCreateInput(campaignCreateParms);
campaignCreate campaignCreate = new campaignCreate(campaignCreateInput);
campaignCreateOutput ccOutput = campaignCreate.Execute(campaignCreateInput);
string abc = ccOutput.result; // This comes out to null
}
catch(Exception ee)
{
Console.WriteLine("\n\n Exception :" + ee.Message); // no exception
}
can anybody show me the right direction and what is wrong with the code.
any help would be much appreciated.
thanks.
I solved this problem and here is code as solution. here listID is precreated List ID in your account in Mailchimp.
private void CreateCampaignAndSend(string apiKey, string listID)
{
Int32 TemplateID = 100;
string campaignID =string.Empty;
// compaign Create Options
campaignCreateOptions campaignCreateOpt = new campaignCreateOptions();
campaignCreateOpt.list_id = listID;
campaignCreateOpt.subject = "subject";
campaignCreateOpt.from_email = "abc#xyz.com";
campaignCreateOpt.from_name = "abc";
campaignCreateOpt.template_id = TemplateID;
// Content
Dictionary<string, string> content = new Dictionary<string, string>();
content.Add("html_ArticleTitle1", "ArticleTitle1");
content.Add("html_ArticleTitle2","ArticleTitle2");
content.Add("html_ArticleTitle3", "ArticleTitle3");
content.Add("html_Article1", "Article1");
content.Add("html_Article2", "Article2");
// Conditions
List<campaignSegmentCondition> csCondition = new List<campaignSegmentCondition>();
campaignSegmentCondition csC = new campaignSegmentCondition();
csC.field = "interests-" + 123; // where 123 is the Grouping Id from listInterestGroupings()
csC.op = "all";
csC.value = "";
csCondition.Add(csC);
// Options
campaignSegmentOptions csOptions = new campaignSegmentOptions();
csOptions.match = "all";
// Type Options
Dictionary<string, string> typeOptions = new Dictionary<string, string>();
typeOptions.Add("offset-units", "days");
typeOptions.Add("offset-time", "0");
typeOptions.Add("offset-dir", "after");
// Create Campaigns
campaignCreate campaignCreate = new campaignCreate(new campaignCreateInput(apiKey, EnumValues.campaign_type.plaintext, campaignCreateOpt, content, csOptions, typeOptions));
campaignCreateOutput ccOutput = campaignCreate.Execute();
List<Api_Error> error = ccOutput.api_ErrorMessages; // Catching API Errors
if (error.Count <= 0)
{
campaignID = ccOutput.result;
}
else
{
foreach (Api_Error ae in error)
{
Console.WriteLine("\n ERROR Creating Campaign : ERRORCODE\t:" + ae.code + "\t ERROR\t:" + ae.error);
}
}
}
I removed the url and archive from the content. Then the campaign was created just fine:
// campaign Create
campaignCreateOptions campaignCreateOpt = new campaignCreateOptions();
campaignCreateOpt.list_id = listId;
campaignCreateOpt.subject = " New Campaign from Someemone";
campaignCreateOpt.from_email = "someone#home.com";
campaignCreateOpt.from_name = "someone";
Dictionary<string, string> content = new Dictionary<string, string>();
content.Add("html", "Lots of cool stuff here.");
campaignSegmentOptions csOptions = new campaignSegmentOptions();
csOptions.match = "any"; // Could not set Condition -- need help for this
// Need to set a Dictionary typeOptions because null is not supported
Dictionary<string,string> typeOptions = new Dictionary<string, string>();
campaignCreateParms campaignCreateParms = new campaignCreateParms(apiKey, EnumValues.campaign_type.trans, campaignCreateOpt, content, csOptions, typeOptions);
campaignCreateInput campaignCreateInput = new campaignCreateInput(campaignCreateParms);
campaignCreate campaignCreate = new campaignCreate(campaignCreateInput);
campaignCreateOutput ccOutput = campaignCreate.Execute(campaignCreateInput);
string newCampaignId = ccOutput.result; // Not null anymore

Multiple complexFilter in Magento's api v2

Currently I’m having some difficulties with using new Magento's soap v2 from c# interface.
With php i was able to do something like this:
$params["created_at"]["from"] = date("Y-m-d H:i:s",Functions::convert_time($dataDa));
$params["created_at"]["to"] = date("Y-m-d H:i:s",Functions::convert_time($dataA));
MageInterface::getSingleton()->shipmentList($params);
In this mode i was able to find list of orders which were created from $dataDa to $dataA without problems. With c# however it seems that only the last one of the selectors work.
My code:
var cpf = new complexFilter[2];
cpf[0] = new complexFilter
{
key = "created_at",
value = new associativeEntity
{
key = "to",
value = uxDataA.DateTime.ToString("yy-MM-dd HH:mm:ss")
}
});
cpf[1] = new complexFilter
{
key = "created_at",
value = new associativeEntity
{
key = "from",
value = uxDataDa.DateTime.ToString("yy-MM-dd HH:mm:ss")
}
});
var filters = new filters();
filters.complex_filter = cpf;
var risultato = mage.salesOrderList(sessionKey, filters);
In this mode only created_at->from criteria is taken in consideration (it's like second complex filter override previous one with the same key). Ideas?
Thanks in advance.
This works for me :
private filters addFilter(filters filtresIn, string key, string op, string value)
{
filters filtres = filtresIn;
if (filtres == null)
filtres = new filters();
complexFilter compfiltres = new complexFilter();
compfiltres.key = key;
associativeEntity ass = new associativeEntity();
ass.key = op;
ass.value = value;
compfiltres.value = ass;
List<complexFilter> tmpLst;
if (filtres.complex_filter!=null)
tmpLst = filtres.complex_filter.ToList();
else tmpLst = new List<complexFilter>();
tmpLst.Add(compfiltres);
filtres.complex_filter = tmpLst.ToArray();
return filtres;
}
and call
{
Mage_Api_Model_Server_V2_HandlerPortTypeClient clientSoap = new Mage_Api_Model_Server_V2_HandlerPortTypeClient();
string sessionId = clientSoap.login(LOG, PASS);
filters filtres = new filters();
filtres = addFilter(filtres, "status", "eq", "processing");
filtres = addFilter(filtres, "created_at", "from", "2014-09-07 08:00:00");
filtres = addFilter(filtres, "created_at", "to", "2014-09-07 00:00:00");
salesOrderEntity[] lst = clientSoap.salesOrderList(sessionId, filtres);
}
Solved, there was a bug (or the feature?) in mage\sales\order\api\v2.php
See more info in this thread: http://www.magentocommerce.com/boards/viewthread/70368/

Categories

Resources