Not able to save multiple results into my table - asp.net-mvc

I am working on ASP.NET MVC project. This is my code :
orderData_Entities ordertable = new orderData_Entities();
DataTable upCSV = (DataTable)TempData["UploadedCSV"];
if (isHeaderAccepted)
{
string[] data = null;
int i = 1;
foreach (DataRow dr in upCSV.Rows)
{
ObjectParameter getemail = new ObjectParameter("email", dr["email"].ToString());
ObjectParameter getpassword = new ObjectParameter("password", dr["password"].ToString());
ObjectParameter getMobile = new ObjectParameter("Mobile", dr["Mobile"].ToString());
var results = ordertable.usp_AppUpdateUserData(idSubAccount,idcategory, getemail.Value.ToString(), getpassword.Value.ToString(), getMobile.Value.ToString());
ordertable.SaveChanges();
i++;
}
}
return RedirectToAction("Index", "BulkUpload");
Here I am looping through all rows and updating results to my table. Currently what's happening here is if I have three rows with email, password and mobile, it is looping through all these three rows one by one and I can see results in debug mode, but while updating to my table, it is updating last row results to all three rows.
So can someone tell me what mistake I am doing here?
Update :
My Stored Procedure is as follows :
ALTER PROCEDURE [dbo].[usp_AppUpdateUserData]
#idSubAccount int = 0,
#idcategory int = 0,
#email nvarchar(100) =0,
#password nvarchar(50) = 0,
#Mobile nvarchar(50) = 0,
AS
BEGIN
Begin
Update tblCustomer
Set
email = #email, password = #password, mobileNo = #Mobile,
where idSubAccount = #idSubAccount and idCategory = #idcategory
END
End
GO

Related

Retrieve data in asp.net MVC from complex stored procedure which return multiple actual table

User Defined Stored Procedure which returns multiple actual table as result set.
CREATE PROCEDURE uspDemo(
#UserID BIGINT=0,
#IsAdmin bit=0,
#Title varchar(120)=''
)AS
BEGIN
------Retrieve Posts------
SELECT * FROM tblPost AS MP INNER JOIN tblUserProfile AS UP ON UP.ID=MP.UserID
WHERE UP.ID=#UserID AND ((#IsAdmin=0 AND MP.IsDeleted=0 AND MP.IsApproved=1)OR (#IsAdmin=1 OR MP.IsDeleted=0 OR MP.IsApproved=1))
----- Retrieve Tags------
SELECT * FROM tblTagMasters AS MT INNER JOIN tblPostTags AS MP ON MT.TagID= MP.TagID
--------Retrieve User likes-----
SELECT * FROM tblUserLikes AS UV INNER JOIN tblPost AS MP ON MP.PostId=UV.PostId
END
I want to convert into list format of all returned actual table from stored procedure according to model in asp.net MVC.
public List<PostView> GetPosts(int userID = 0, string s = "")
{
IEnumerable<PostView> query = null;
using (var db = new MVCDatabase())
{
var cmd = db.Database.Connection.CreateCommand();
cmd.CommandText = "[dbo].[uspDemo]";
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add(new SqlParameter("#UserID", userID));
cmd.Parameters.Add(new SqlParameter("#IsAdmin", 0));
cmd.Parameters.Add(new SqlParameter("#Title", s));
try
{
db.Database.Connection.Open();
using (var result = cmd.ExecuteReader())
{
var Posts = ((IObjectContextAdapter)db).ObjectContext.Translate<PostView>(result).ToList();
result.NextResult();
var tags = ((IObjectContextAdapter)db).ObjectContext.Translate<TagView>(result).ToList();
result.NextResult();
var uservotes = ((IObjectContextAdapter)db).ObjectContext.Translate<UserVoteView>(result).ToList();
Posts.ForEach(z =>
{
z.TagMaster = tags.Where(x => x.PostId == z.PostId).ToList();
z.UserLike = uservotes.Where(x => x.PostId == z.PostId).ToList();
});
query = Posts;
}
}
catch (Exception ex)
{
MSError.Trace(ex);
}
finally
{
db.Database.Connection.Close();
cmd.Dispose();
}
return query.ToList();
}
}
Throwing an ArgumentNullException
Help me to find out the solution.
Here is a demo how to do it. Using System.data and System.Linq you can do below.
var cmd = db.Database.Connection.CreateCommand();
cmd.CommandText = "[dbo].[uspDemo]";
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add(new SqlParameter("#UserID", userID));
cmd.Parameters.Add(new SqlParameter("#IsAdmin", 0));
cmd.Parameters.Add(new SqlParameter("#Title", s));
SqlDataAdapter da = new SqlDataAdapter(); //adapter
DataSet ds = new DataSet(); //dataset
cmd.CommandType = CommandType.StoredProcedure;
da = new SqlDataAdapter(cmd);
da.Fill(ds); //fill dataset with multiple select
var Posts = (from DataRow row in ds.Tables[0].Rows //0 means 1st select
select new Posts //Posts model to map
{
test = row["test"].ToString(), //test is the column name from select
test1 = Convert.ToDecimal(row["test1"])
}).ToList();
var Tags = (from DataRow row in ds.Tables[1].Rows //1 means 2nd select
select new Tags //Tags model to map
{
test = row["test"].ToString(), //test is the column name from select
test1 = Convert.ToDecimal(row["test1"])
}).ToList();
var User = (from DataRow row in ds.Tables[2].Rows //2 means 3rd select
select new User //User model to map
{
test = row["test"].ToString(), //test is the column name from select
test1 = Convert.ToDecimal(row["test1"])
}).ToList();

How to get data from a stored Procedure that joins 3 tables and takes 3 different Parameters asp.net MVC

I have to create something that executes a stored Procedure, and depending on the parameters passed it will show data from different Tables. I am using EF model.
The Parameters are #Username, #FamilyID, #CategoryID
If you run it with Just #Username it will retrieve Families
If you run it with #Username and #FamilyID it will retrieve Categories
If you run it with all parameters it will return Report Names
I'm very new to ASP.Net, and I was seeking for help to display the results of this stored procedure. I have succeeded on executing a stored procedure that uses one single table, but unfortunately haven't with this specific one...
SP
ALTER Procedure [Report].[Rep_ReportListforUser]
#UserName varchar(50),
#FamilyId int = 0 ,
#CategoryID int = 0
as
Set nocount on
If #FamilyId = 0
Begin
Select RF.ID FamilyID,RF.Family FamilyName,1 Allowed
from Rep_ReportFamilies RF
End
Else If #CategoryID = 0
--Categories
Begin
Select Cat.Id CategoryID , Cat.Category ,Case when UF.ReportFamilyId is null then 0 else 1 end Allowed
from dbo.Rep_ReportFamilies RF Left Join dbo.Rep_User_Family UF On RF.ID = UF.ReportFamilyID
Join dbo.Rep_ReportCategories Cat on Cat.FamilyID = RF.ID
where UserId = (Select UserID from Report.Users where Username = #UserName)
and RF.ID = #FamilyID
End
Else
Begin
Select RL.ReportID , ReportDescription ReportName, Case when RU.Userid is null then 0 else 1 end Allowed
from dbo.Rep_ReportNames RL
Left Join dbo.Rep_Report_Users RU on RU.ReportId = RL.ReportId
Where RL.CategoryID = #CategoryID and
RU.userid = (Select userid from Report.Users
where Username = #UserName)
Order by ReportDescription
end
Code
SqlParameter[] parameters = new SqlParameter[]
{
new SqlParameter ("#UserName","john"),
new SqlParameter ("#FamilyId",10),
new SqlParameter ("#CategoryID",24),
};
var families = context.Database.SqlQuery<Rep_ReportFamilies>("[Report].Rep_ReportListforUser #Family");
var username = context.Database.SqlQuery<Rep_ReportNames>("[Report].Rep_ReportListforUser #UserName");
var category = context.Database.SqlQuery<Rep_ReportNames>("[Report].Rep_ReportListforUser #CategoryID");
return View();
}
Hope Someone can Help
Happy Coding!
Need to update your code the following way.
Updated Code.
// If you run it with Just #Username it will retrieve Families
var families = context.Database.SqlQuery<Rep_ReportFamilies>("EXEC [Report].Rep_ReportListforUser #UserName, #FamilyId, #CategoryID ",
new SqlParameter ("#UserName","john"),
new SqlParameter ("#FamilyId",0),
new SqlParameter ("#CategoryID",0);
//If you run it with #Username and #FamilyID it will retrieve Categories
var username = context.Database.SqlQuery<Rep_ReportFamilies>("EXEC [Report].Rep_ReportListforUser #UserName, #FamilyId, #CategoryID ",
new SqlParameter ("#UserName","john"),
new SqlParameter ("#FamilyId",10),
new SqlParameter ("#CategoryID",0);
//If you run it with all parameters it will return Report Names
var category = context.Database.SqlQuery<Rep_ReportFamilies>("EXEC [Report].Rep_ReportListforUser #UserName, #FamilyId, #CategoryID ",
new SqlParameter ("#UserName","john"),
new SqlParameter ("#FamilyId",10),
new SqlParameter ("#CategoryID",24);

How can I call stored procedure inside for loop everytime and store results in Database

Hi I am working on ASP.NET MVC project. This is my code :
string[] dt1;
for (int ic = 0; ic < dt.Count() - 1; ic++)
{
dt1 = new string[3];
dt1 = dt[ic].Split('|');
var date = Convert.ToDateTime(dt1[0].Substring(0, dt1[0].IndexOf("GMT")).Trim()).ToShortDateString();
var time = Convert.ToDateTime(dt1[0].Substring(0, dt1[0].IndexOf("GMT")).Trim()).ToShortTimeString();
//Calling Stroed Procedure
var schedulesp = orderdata.uspApp_InsertScheduler(Convert.ToInt32(outputresults), newid, Name, Convert.ToDateTime(date),time);
orderdata.SaveChanges();
}
Here I am looping through dates and times. I need to insert new records every time when i loop through date and time, that is 5 times I need to insert records.
But when I run above code, it is always saving only last results that is 5th result.
So how can i save all results into my database??
Update: This is the store procedure code :
ALTER PROCEDURE [dbo].[uspApp_InsertScheduler]
#ID int = 0,
#UserID int = 0,
#ReportName nvarchar(50) = 0,
#ScheduleStartDate date,
#SchedulestartTime nvarchar(10) = 0
AS
BEGIN
IF EXISTS (SELECT * FROM App_ReportsScheduler where id = #ID )
BEGIN
UPDATE App_ReportsScheduler
SET
reportName = #ReportName, schedule_StartDate = #ScheduleStartDate, schedule_starttime = #SchedulestartTime
where id = #ID
END
ELSE
BEGIN
INSERT INTO App_ReportsScheduler (ID, UserID, reportName,schedule_StartDate,schedule_starttime)
values ( #ID, #UserID,#ReportName,#ScheduleStartDate,#SchedulestartTime)
END
END
GO
Just put orderdata.SaveChanges(); out side of your loop.

The SqlParameter is already contained by another SqlParameterCollection

I'm using EF DbContext SqlQuery to get a list of paged objects using PagedList (https://github.com/TroyGoode/PagedList) and I'm getting the following error:
"The SqlParameter is already contained by another SqlParameterCollection"
Here's my repository code:
var db = (DbContext)DataContext;
const string sqlString =
#"
WITH UserFollowerList
AS
(
SELECT uf.FollowId
FROM UserFollow uf
WHERE uf.UserId = #UserId
)
SELECT * FROM UserFollowerList uf
INNER JOIN [User] u ON uf.FollowId = u.UserId
WHERE IsDeleted = 0
"
;
var userIdParam = new SqlParameter("UserId", SqlDbType.Int) {Value = userId};
var userList =
db.Database.SqlQuery<User>(sqlString, userIdParam)
.ToPagedList(pageIndex, pageSize);
return userList;
But when I call the ToList extension on the SqlQuery statement it works fine:
var userList = db.Database.SqlQuery<User>(sqlString, userIdParam).ToList();
PagedList code:
private PagedList(IQueryable<T> source, int pageIndex, int pageSize)
{
TotalItemCount = source.Count();
PageSize = pageSize;
PageIndex = pageIndex;
PageCount = TotalItemCount > 0 ? (int)Math.Ceiling(TotalItemCount / (double)PageSize) : 0;
HasPreviousPage = (PageIndex > 0);
HasNextPage = (PageIndex < (PageCount - 1));
IsFirstPage = (PageIndex <= 0);
IsLastPage = (PageIndex >= (PageCount - 1));
ItemStart = PageIndex * PageSize + 1;
ItemEnd = Math.Min(PageIndex * PageSize + PageSize, TotalItemCount);
// add items to internal list
if (TotalItemCount > 0)
Data = pageIndex == 0 ? source.Take(pageSize).ToList() : source.Skip((pageIndex) * pageSize).Take(pageSize).ToList();
}
I've already the solution below without any success:
var param = new DbParameter[] { new SqlParameter { ParameterName = "UserId", Value = userId }
What can I do to fix the error I'm experiencing?
FYI I just saw this exact same error message when using an EF 5 DbContext to call context.ExecuteQuery<my_type>(...); with an array of SqlParameters, where my_type had a string but the SQL statement was returning an int for one of the parameters.
The error was really in the return mapping, but it said the SqlParameter was to blame, which threw me off for a little while.
When using a generic call to SqlQuery such as db.Database.SqlQuery you must iterate to the last record of the returned Set in order for the result set and associated parameters to be released. PagedList uses source.Take(pageSize).ToList() which will not read to the end of the source set. You could work around this by doing something like foreach(User x in userList) prior to returning the result.
I tried the following solution from Diego Vega at http://blogs.msdn.com/b/diego/archive/2012/01/10/how-to-execute-stored-procedures-sqlquery-in-the-dbcontext-api.aspx and it worked for me:
var person = context.Database.SqlQuery<Person>(
"SELECT * FROM dbo.People WHERE Id = {0}", id);
When you are using parameters on (SqlQuery or ExecuteSqlCommand) you can't use theme by another query until old query dispose.
in PagedList method you use "source.Count();" at first and the end line you are using "source" again. that's not correct.
you have 2 solution.
1- send param to PagedList Method and new theme for each using SqlQuery or ExecuteSqlCommand
2-remove PagedList and send your paging param to SqlQuery or ExecuteSqlCommand like this :
const string sqlString =
#"
WITH UserFollowerList
AS
(
SELECT uf.FollowId,ROW_NUMBER() OVER(ORDER BY uf.FollowId ) RowID
FROM UserFollow uf
WHERE uf.UserId = #UserId
)
SELECT * FROM UserFollowerList uf
INNER JOIN [User] u ON uf.FollowId = u.UserId
WHERE IsDeleted = 0 and RowID BETWEEN (((#PageNumber- 1) *#PageSize)+ 1) AND (#PageNumber * #PageSize))
"
;
Just encountered this exception even though it was my first query to the database with a single param. And having the Context in a 'using'.
When I 'hardcoded' the queryparameter valies into the string it worked correct for some reason. But as soon as I used SqlParameter it gave me the "The SqlParameter is already contained by another SqlParameterCollection"
This didn't work:
context.Database.SqlQuery<int?>(query, new SqlParameter("#TableName", tableName));
This did:
context.Database.SqlQuery<int>(query, new SqlParameter("#TableName", tableName));
The difference being the return type int? vs int. So for anyone reading this. Please also check your return type of the SqlQuery even when you're sure it should work.
This is old, but I ran into the same problem and someone has thought of the solution here
https://dotnetfiddle.net/GpEd95
Basically you need to split this up into a few steps in order to get your paged query
//step 1 set the page numbers
int pageNumber = 1;
int pageSize = 2;
//step 2 set your parameters up
var parm2 = new SqlParameter("param1", "Kevin");
var parm1 = new SqlParameter("param1", "Kevin");
var pageParm = new SqlParameter("#p2", (pageNumber - 1) * pageSize);
var pageSizeParm = new SqlParameter("#p3", pageSize);
//step 3 split your queries up into search and count
var sqlString = #"SELECT FT_TBL.*
FROM EquipmentMaintenances AS FT_TBL
INNER JOIN FREETEXTTABLE(vw_maintenanceSearch, Search, #param1) AS KEY_TBL ON FT_TBL.EquipmentMaintenanceID = KEY_TBL.[KEY]
WHERE FT_TBL.Status = 1
ORDER BY RANK DESC, FT_TBL.EquipmentMaintenanceID DESC OFFSET #p2 ROWS FETCH NEXT #p3 ROWS ONLY";
var sqlCountString = #"SELECT COUNT(1)
FROM EquipmentMaintenances AS FT_TBL
INNER JOIN FREETEXTTABLE(vw_maintenanceSearch, Search, #param1) AS KEY_TBL ON FT_TBL.EquipmentMaintenanceID = KEY_TBL.[KEY]
WHERE FT_TBL.Status = 1
";
//step 4 run your queries c# doesn't like the reusing of parameters so create 2 (e.g Kevin) so your results will run correctly.
var main = _db.Database.SqlQuery<EquipmentMaintenance>(sqlString, parm1, pageParm, pageSizeParm).ToList();
var count = _db.Database.SqlQuery<int>(sqlCountString, parm2).FirstOrDefault();
//step 5 created your paged object - I'm using x.pagedlist
var paged = new StaticPagedList<EquipmentMaintenance>(main, pageNumber, pageSize, count);
Obviously your now passing this back to your view or other function for display.

Problem with Json

Im having this weird problem with creating Json dynamically.... for some reason this doesnt work
var jsonData = new
{
total = totalPages,
page = page,
records = totalRecords,
rows = (
from company in companies
select new
{
i = company.Id,
cell = new string[] { company.Id.ToString(), ""+company.Name.ToString()+"" }
}).ToArray()
};
Its giving me a weird "Could not translate expression....... into sql" exception
but with this minor change it works just fine
var jsonData = new
{
total = totalPages,
page = page,
records = totalRecords,
rows = (
from company in companies
select new
{
i = company.Id,
cell = new string[] { company.Id.ToString(), ""+company.Name.ToString()+"" }
}).ToArray()
};
Notice that the change is just to make id=5 instead of dynamic.
also, this works correctly but I dont like it.
var jsonData = new
{
total = totalPages,
page = page,
records = totalRecords,
rows = (
from company in companies
select new
{
i = company.Id,
cell = new string[] { company.Id.ToString(), ""+company.Name.ToString()+"" }
}).ToArray()
};
I'm not sure if this will solve your problem, but assuming companies is an IQueryable from the DataContext, try calling ToList() on it so that the select expression doesn't get sent to the database.
var jsonData = new
{
total = totalPages,
page = page,
records = totalRecords,
rows = (
from company in companies.ToList()
select new
{
i = company.Id,
cell = new string[] { company.Id.ToString(), ""+company.Name.ToString()+"" }
}).ToArray()
};
It's trying to translate the i to SQL and failing. The query that gets generated is something close to
SELECT companies.Id,
'' + companies.Name + ''
FROM companies
Basically, your string concatenation is being sent to your SQL server.

Resources