Insert data into database using LINQ - c#

I wrote a very simple method. It saves data from class DayWeather to the database. Method checks if line with that day exist in table and update her or create a new line.
I am doing it by adding new class for LINQ and move table from Server Inspector to the constructor. It generate new class WeatherTBL.
Method itself looks like this:
public static void SaveDayWeather(DayWeather day)
{
using (DataClassesDataContext db = new DataClassesDataContext())
{
var existingDay =
(from d in db.WeatherTBL
where d.DateTime.ToString() == day.Date.ToString()
select d).SingleOrDefault<WeatherTBL>();
if (existingDay != null)
{
existingDay.Temp = day.Temp;
existingDay.WindSpeed = day.WindSpeed;
existingDay.Pressure = day.Pressure;
existingDay.Humidity = day.Humidity;
existingDay.Cloudiness = day.Cloudiness;
existingDay.TypeRecip = day.TypeRecip;
db.SubmitChanges();
}
else
{
WeatherTBL newDay = new WeatherTBL();
newDay.DateTime = day.Date;
newDay.Temp = day.Temp;
newDay.WindSpeed = day.WindSpeed;
newDay.Pressure = day.Pressure;
newDay.Humidity = day.Humidity;
newDay.Cloudiness = day.Cloudiness;
newDay.TypeRecip = day.TypeRecip;
db.WeatherTBL.InsertOnSubmit(newDay);
db.SubmitChanges();
}
}
}
When I tried to call him from UnitTest project:
[TestMethod]
public void TestDataAccess()
{
DayWeather day = new DayWeather(DateTime.Now);
DataAccessClass.SaveDayWeather(day);
}
It write, that test has passed successfully. But if look into table, it has`t chanched.
No error messages shows. Does anyone know whats the problem?
P.S. Sorry for my bad English.
UDP
Problem was in that:
"...db maybe copied to the debug or release folder at every build, overwriting your modified one". Thanks #Silvermind

I wrote simple method to save employee details into Database.
private void AddNewEmployee()
{
using (DataContext objDataContext = new DataContext())
{
Employee objEmp = new Employee();
// fields to be insert
objEmp.EmployeeName = "John";
objEmp.EmployeeAge = 21;
objEmp.EmployeeDesc = "Designer";
objEmp.EmployeeAddress = "Northampton";
objDataContext.Employees.InsertOnSubmit(objEmp);
// executes the commands to implement the changes to the database
objDataContext.SubmitChanges();
}
}

Please try with lambda expression. In your code, var existingDay is of type IQueryable
In order to insert or update, you need a variable var existingDay of WeatherTBL type.
Hence try using below..
var existingDay =
db.WeatherTBL.SingleOrDefault(d => d.DateTime.Equals(day.Date.ToString()));
if(existingDay != null)
{
//so on...
}
Hope it should work..

Linq to SQL
Detail tc = new Detail();
tc.Name = txtName.Text;
tc.Contact = "92"+txtMobile.Text;
tc.Segment = txtSegment.Text;
var datetime = DateTime.Now;
tc.Datetime = datetime;
tc.RaisedBy = Global.Username;
dc.Details.InsertOnSubmit(tc);
try
{
dc.SubmitChanges();
MessageBox.Show("Record inserted successfully!");
txtName.Text = "";
txtSegment.Text = "";
txtMobile.Text = "";
}
catch (Exception ex)
{
MessageBox.Show("Record inserted Failed!");
}

Related

how to optimize the time in executing the query in c# react

I am new to React and new to Web API. I am uploading data in a tabulator in react front end from the value that I am passing through the web API. I am passing value through the getReports function like this:
[HttpPost]
[Route("GetReports")]
public IHttpActionResult GetReports(string jwt, List<object> data)
{
if (!Common.VerificationToken.VerifyJWToken(jwt))
{
return null;
}
var to = data[0];
var from = data[1];
DateTime toDate = Convert.ToDateTime(to);
DateTime fromDate = Convert.ToDateTime(from);
var ReportData = db.T_CQL_COIL_DESC.Where(t => t.CCD_CREATED_ON >= toDate &&
t.CCD_CREATED_ON <= fromDate).ToList();
ReportsDTO dto = new ReportsDTO();
List<ReportsDTO> ReportDTO = new List<ReportsDTO>();
try
{
foreach (var report in ReportData)
{
List<vehicledetail> vehicle = new List<vehicledetail>();
var imgurl = "https://firebasestorage.googleapis.com/v0/b/tsl-coil-qlty-
monitoring-dev.appspot.com/";
dto = new ReportsDTO();
dto.Type = report.CCD_OP_TYPE;
dto.ID = report.CCD_COIL_ID;
vehicle = GetVehicleID(dto.ID);
vehicledetail vehicledetails = vehicle[0];
dto.vehicleno = vehicledetails.vehicleno.ToString();
dto.wagonno = vehicledetails.wagonno.ToString();
dto.Active = report.CCD_ACTIVE;
dto.ImgURL = report.CCD_IMAGE_URL != null ? imgurl + report.CCD_IMAGE_URL : "NA";
dto.Desc = report.CCD_VIEW_DESC != null ? report.CCD_VIEW_DESC : "NA";
ReportDTO.Add(dto);
}
return Ok(ReportDTO);
}
catch (Exception ex)
{
return Content(HttpStatusCode.NoContent, "Something went wrong");
}
}
The data in vehicledetail in vehicledetail vehicledetails = vehicle[0]; is getting populated from this function:
public List<vehicledetail> GetVehicleID(string coilID)
{
List<vehicledetail> vehicle = new List<vehicledetail>();
vehicledetail vehicledetails = new vehicledetail();
string oradb = Utilities.STAR_DB;
OracleConnection conn = new OracleConnection(oradb);
string query = "SELECT a.Vbeln, b.WAGON_NO FROM sapr3.lips a, sapr3.ZVTRRDA b WHERE
a.MANDT='600' AND a.CHARG='" + coilID + "' AND a.LFIMG > 0 AND a.MANDT = b.MANDT AND
a.VBELN = b.VBELN";
OracleDataAdapter da = new OracleDataAdapter(query, conn);
conn.Open();
DataTable dt = new DataTable();
da.Fill(dt);
foreach (DataRow row in dt.Rows)
{
vehicledetails.vehicleno = row["VBELN"].ToString();
vehicledetails.wagonno = row["WAGON_NO"].ToString();
}
conn.Close();
vehicle.Add(vehicledetails);
return (vehicle);
}
It is working fine but it is taking 30 seconds to load the below data:
How do I optimize this . Please help. Note: that it is taking 30 seconds to upload this data
Few other things aside, the major problem seems to be that you are querying database for each vehicle.
In this particular scenario it might very well be better to select all vehicle ids and query them all.
var vehicleIds = reportData.SelectMany(t => t.ID);
You can then form a query that will get all vehicle details together. This will reduce the number of database calls and it can have massive impact on time.
Another thing to check is if there's any index created on the vehicle id column in database as that may also help speed things up.

Update list object to database using InsertAllOnSubmit

I'm trying to save changes to database using Linq 2 Sql, using InserAllOnSubmit method, it neither inserts the records nor throws errors/exceptions.
Please help me if I have done any mistake in the code.
Thanks in advance.
public void UpdateCoachingAssessmentInfo(CoachingAssessmentViewModel model)
{
Guid userGuid = model.UserGuid;
try
{
using (var ctxAdmin = new MemberDataContext(ConfigurationManager.ConnectionStrings[Constants.CONFIG_KEY_MEMBER_CONNECTION_STRING].ToString()))
{
List<CAT> userCat = new List<CAT>();
List<QandR> userQr = model.QuestionResponseIds;
foreach (var x in userQr)
{
CAT objCAT = new CAT();
objCAT.userGuid = model.UserGuid;
objCAT.Question_Id = x.QuestionId;
if (x.OptionId != null && x.OptionId != 0)
{
objCAT.Option_Id = x.OptionId;
objCAT.Option_Response = null;
}
else
{
objCAT.Option_Response = x.OptionResponse ?? null;
objCAT.Option_Id = null;
}
objCAT.createDate = DateTime.Now;
objCAT.updateDate = DateTime.Now;
userCat.Add(objCAT);
}
ctxAdmin.CATs.InsertAllOnSubmit(userCat);
}
UpdateCoachingAssessmentEligibility(userGuid);
}
catch (Exception ex)
{
throw new Exception("Unable to save changes to db.", ex);
}
}
You should add ctxAdmin.CATs.SubmitChanges() after ctxAdmin.CATs.InsertAllOnSubmit(userCat).
According to the documentation
The added entities will not be in query results until after SubmitChanges has been called.
Let me know if it helps.

Error when collecting multiple resultset from stored procedure

I have a stored procedure which I have written. I am trying to collecting multiple result set from it. But unfortunately I am getting an error
A first chance exception of type 'System.Data.SqlClient.SqlException' occurred in System.Data.dll.
The message is the error I keep seeing.
I have tried all I can but don't know were the error is, I have tested my stored procedure it works fine.
Stored procedure:
CREATE PROCEDURE [dbo].[Collectcompanyservicewithpackages]
#CompanyID int
AS
select *
from Serviceduration
where Client_CompanyID = #CompanyID;
select Serviceitem.*
from Serviceduration, Serviceitem
where Client_CompanyID = #CompanyID
and Serviceduration.ServicedurationID = Serviceitem.ServicedurationID;
select ServiceitemPackage.*
from Serviceduration, Serviceitem, ServiceitemPackage
where Client_CompanyID = #CompanyID
and Serviceduration.ServicedurationID = Serviceitem.ServicedurationID
and Serviceitem.ServiceitemID = ServiceitemPackage.ServiceitemID
Database modules:
Snippet
public List<Serviceview> GetFirmServiceswithpackages_sp(int CompanyID)
{
List<Serviceview> allservices = null;
IEnumerable<Serviceduration> servicedurations = null;
IEnumerable<Serviceitem> serviceitems = null;
IEnumerable<ServiceitemPackage> serviceitempackages = null;
using(context){
Debug.WriteLine("App got here for starters .........................");
// If using Code First we need to make sure the model is built before we open the connection
// This isn't required for models created with the EF Designer
//context.Database.Initialize(force: false);
// Create a SQL command to execute the sproc
var cmd = context.Database.Connection.CreateCommand();
cmd.CommandText = "Collectcompanyservicewithpackages #CompanyID";
cmd.CommandType = CommandType.StoredProcedure;
DbParameter inputparameter = new SqlParameter();
inputparameter.DbType = DbType.Int64;
inputparameter.ParameterName = "CompanyID";
inputparameter.Value = CompanyID;
inputparameter.Direction = ParameterDirection.Input;
cmd.Parameters.Add(inputparameter);
try
{
// Run the sproc
context.Database.Connection.Open();
var reader = cmd.ExecuteReader();
// Read Blogs from the first result set
var durations = ((IObjectContextAdapter)context)
.ObjectContext
.Translate<Serviceduration>(reader, "Servicedurations", MergeOption.AppendOnly);
servicedurations = this.Extractdurations(durations);
Debug.WriteLine("No of duration "+servicedurations.Count());
// Move to second result set and read Serviceitems in cart
reader.NextResult();
var services4sale = ((IObjectContextAdapter)context)
.ObjectContext
.Translate<Serviceitem>(reader, "Serviceitems", MergeOption.AppendOnly);
serviceitems = this.Extractservices(services4sale);
Debug.WriteLine("No of services "+serviceitems.Count() );
// Move to second result set and read Serviceitems in cart
reader.NextResult();
var packages = ((IObjectContextAdapter)context)
.ObjectContext
.Translate<ServiceitemPackage>(reader, "ServiceitemPackages", MergeOption.AppendOnly);
serviceitempackages = this.Extractpackages(packages);
Debug.WriteLine("No of packages ...."+ serviceitempackages.Count());
allservices = this.ReturnServiceincart(servicedurations, serviceitems, serviceitempackages);
}
catch(SqlException e){
Debug.WriteLine("Cause of the error "+e.InnerException.Message);
}
finally
{
context.Database.Connection.Close();
}
}
return allservices;
}
//The methods below are used to extract Enumerables from the Object Resultset. I would love to call them helper methods
//This is the help method that would help us to do the final crafting of our stored procedure run around
private List<Serviceview> ReturnServiceincart(IEnumerable<Serviceduration> durations, IEnumerable<Serviceitem> services, IEnumerable<ServiceitemPackage> packages)
{
List<Serviceview> allservices = new List<Serviceview>();
if(services != null){
foreach(var service in services){
Serviceview view = new Serviceview()
{
Name = service.Name,
Cost = service.Cost,
Description = service.Description,
Durationname = durations.Where(item=>item.ServicedurationID == service.ServicedurationID).Select(item=>item.Duration).SingleOrDefault<string>(),
IsVisible = service.IsVisible,
Packages = Returnpackages(service.ServiceitemID, packages) //Note we are not passing service.ServiceitemPackage, cos we are avoiding a lazy loading cos it already been returned in stored procedure.
};
}
}
return allservices;
}
private IEnumerable<Serviceduration> Extractdurations(ObjectResult<Serviceduration> durations)
{
IEnumerable<Serviceduration> servicedurations = durations.AsEnumerable<Serviceduration>();
return servicedurations;
}
private IEnumerable<Serviceitem> Extractservices(ObjectResult<Serviceitem> services4sale)
{
IEnumerable<Serviceitem> serviceitems = services4sale.AsEnumerable<Serviceitem>();
return serviceitems;
}
private IEnumerable<ServiceitemPackage> Extractpackages(ObjectResult<ServiceitemPackage> packages)
{
IEnumerable<ServiceitemPackage> servicepackages = packages.AsEnumerable<ServiceitemPackage>();
return servicepackages;
}
//Because the packages here would contain all packages for all company services we need to filter with a service ID
private List<string> Returnpackages(int ServiceitemID, IEnumerable<ServiceitemPackage> packageitems)
{
List<string> packages = new List<string>();
foreach(var package in packageitems){
if(package.ServiceitemID == ServiceitemID)
packages.Add(package.PackageName);
}
return packages;
}
Changes made below
cmd.CommandText = "Collectcompanyservicewithpackages";
After making a change to the query. I get the error message
The result of the query can not be enumerable more than once.
The new error is on the line
allservices = this.ReturnServiceincart(servicedurations, serviceitems, serviceitempackages);
cmd.CommandText = "Collectcompanyservicewithpackages";
This line solved the magic.
After this I closed the command and the reader object.
It works fine now.

C# Create employee. Save to SQL Database using EF

I'm saving an employee to a SQL database. I'm saving Firstname, Lastname, Username and Password. How should I do this to prevent saving more than one identical username?
I've tried this:
private void CreateEmployee()
{
using (var db = new TidrapportDBEntities())
{
var user = (from p
in db.Login
where p.username != null
select p).ToList();
foreach (var vUser in user)
{
if (vUser.username == textBoxUsername.Text)
{
labelSuccessFail.Visible = true;
labelSuccessFail.Text = "Accountname already exist.";
break;
}
else
{
var userInfo = new Login();
var persInfo = new PersonalInformation();
persInfo.firstname = textBoxFirstname.Text;
persInfo.lastname = textBoxLastname.Text;
userInfo.username = textBoxUsername.Text;
userInfo.password = textBoxPassword.Text;
userInfo.employeeId = persInfo.employeeId;
db.Login.Add(userInfo);
db.PersonalInformation.Add(persInfo);
db.SaveChanges();
textBoxFirstname.Text = string.Empty;
textBoxLastname.Text = string.Empty;
textBoxUsername.Text = string.Empty;
textBoxPassword.Text = string.Empty;
labelSuccessFail.Visible = true;
labelSuccessFail.Text = "Successfully created account.";
}
}
}
}
Any tips what I can try?
Kind regards,
Kristian
You should have a unique constraint on the username field. Not sure if you're doing code first, model first or DB first in your EF, but you should be able to google how to get it set on your database using the right method. That will throw an exception if you try to save one, so that makes sure you can't have more than one.
You could also use LINQ statement to restrict the list of users to the user name you wish to create and then you're just down to checking a bool to see if a row is returned or not. That way you're not having to read the entire database table (which your "toList" is doing).
In your code example, you're getting all the users where they have a user name, you're then looping round them, but your conditional code only really works if the first one matches the user name you're trying to save, otherwise you are going to try and recreate a duplicate the second time around. So just to get your code working you could try:
private void CreateEmployee()
{
using (var db = new TidrapportDBEntities())
{
var user = (from p
in db.Login
where p.username != null
select p).ToList();
bool found = false;
foreach (var vUser in user)
{
if (vUser.username == textBoxUsername.Text)
{
found = true;
labelSuccessFail.Visible = true;
labelSuccessFail.Text = "Accountname already exist.";
break;
}
}
if(!found)
{
var userInfo = new Login();
var persInfo = new PersonalInformation();
persInfo.firstname = textBoxFirstname.Text;
persInfo.lastname = textBoxLastname.Text;
userInfo.username = textBoxUsername.Text;
userInfo.password = textBoxPassword.Text;
userInfo.employeeId = persInfo.employeeId;
db.Login.Add(userInfo);
db.PersonalInformation.Add(persInfo);
db.SaveChanges();

How to move records from one table to another in linq

I have a ProductLevel table in an SQL database. It contains the products for a store. I want to copy these records into a ProductLevelDaily table at the time the user logs onto the hand held device in the morning.
As they scan items the bool goes from false to true so at anytime they can see what items are left to scan/check.
From the mobile device I pass the siteID and date to the server:
int userID = int.Parse(oWebRequest.requestData[5]); and a few other things
IEnumerable<dProductLevelDaily> plditems
= DSOLDAL.CheckProductDailyLevelbySiteCount(siteID, currentDate);
This checks if there are any records already moved into this table for this store. Being the first time this table should be empty or contain no records for this store on this date.
if (plditems.Count() == 0) // is 0
{
IEnumerable<dProductLevel> ppitems = DSOLDAL.GetProductsbySite(siteID);
// this gets the products for this store
if (ppitems.Count() > 0)
{
dProduct pi = new dProduct();
foreach (dProductLevel pl in ppitems)
{
// get the product
pi = DSOLDAL.getProductByID(pl.productID, companyID);
dProductLevelDaily pld = new dProductLevelDaily();
pld.guid = Guid.NewGuid();
pld.siteID = siteID;
pld.statusID = 1;
pld.companyID = companyID;
pld.counted = false;
pld.createDate = DateTime.Now;
pld.createUser = userID;
pld.productID = pl.productID;
pld.name = "1000"; // pi.name;
pld.description = "desc"; // pi.description;
DSOLDAL.insertProductLevelDailyBySite(pld);
}
}
}
On the PDA the weberequest response returns NULL
I can't see what the problem is and why it wont work.
The insert is in DSOLDAL:
public static void insertProductLevelDailyBySite(dProductLevelDaily pld)
{
dSOLDataContext dc = new dSOLDataContext();
try
{
dc.dProductLevelDailies.InsertOnSubmit(pld);
// dProductLevelDailies.Attach(pld, true);
dc.SubmitChanges();
}
catch (Exception exc)
{
throw new Exception(getExceptionMessage(exc.Message));
}
finally
{
dc = null;
}
}
This code works until I put the foreach loop inside with the insert
IEnumerable<dProductLevelDaily> plditems
= DSOLDAL.CheckProductDailyLevelbySiteCount(siteID, s);
if (plditems.Count() == 0) // plditems.Count() < 0)
{
IEnumerable<dProductLevel> ppitems = DSOLDAL.GetProductsbySite(siteID);
if (ppitems.Count() > 0)
{
oWebResponse.count = ppitems.Count().ToString();
oWebResponse.status = "OK";
}
else
{
oWebResponse.count = ppitems.Count().ToString();
oWebResponse.status = "OK";
}
}
else
{
oWebResponse.count = "2"; // plditems.Count().ToString();
oWebResponse.status = "OK";
}
These kind of bulk operations aren't very well matched to what Linq-to-SQL does.
In my opinion, I'd do this using a stored procedure, which you could include in your Linq-to-SQL DataContext and call from there.
That would also leave the data on the server and just copy it from one table to the other, instead of pulling down all data to your client and re-uploading it to the server.
Linq-to-SQL is a great tool - for manipulating single objects or small sets. It's less well suited for bulk operations.

Categories