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

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();

Related

GROUP BY LINQ ASP.NET MVC

Let's suppose we have a Linq query like this:
int companyID = Convert.ToInt32(((UserIdentity)User.Identity).CompanyId);
var stock = from i in _stockService.GetStock()
join ur in _inventoryService.GetInventory() on i.ProductID equals ur.Id
where ur.ComapnyId == companyID
select new StockVM
{
Product = ur.ItemName,
Quantity = i.Quantity,
BatchID = i.BatchID,
StockStatus = i.StockStatus,
MfgDate = i.MfgDate,
ExpDate = i.ExpDate,
};
Result
How to do a "Group By Product" with sum of Quantity in this linq query?
I need to only get max ExpDate firstOrDefault
try something like this:
int companyID = Convert.ToInt32(((UserIdentity)User.Identity).CompanyId);
var stock = from i in _stockService.GetStock()
join ur in _inventoryService.GetInventory() on i.ProductID equals ur.Id
where ur.ComapnyId == companyID
group new { Quantity = i.Quantity } by new { ur.ItemName } into g
select new { Product = g.Key, TotalQuantity = g.Sum() } ).ToList() ;
List<StockVM> _lst = new List<StockVM>();
foreach(var item in stock ){
StockVM row = new StockVM();
row.Product = item.ItemName;
//....
_lst.Add(row);
}

How to include FirstOrDefault() in ToList()

I want to get only one file for each recipe.
var UploadedFiles = (from rec in db.Recipes
join files in db.Files on rec.Id equals files.RecipeId
select new
{
files.Id,
files.Path,
files.RecipeId,
rec.Name,
rec.Description,
rec.Category,
rec.CookTime
}).ToList();
return new JsonResult { Data = UploadedFiles, JsonRequestBehavior = JsonRequestBehavior.AllowGet };
You could use group join instead of regular join, I presume it is also more efficient than the previous answer (with the let), although I am not fully aware of EF query optimizations in this case
var UploadedFiles = (from rec in db.Recipes
join files in db.Files on rec.Id equals files.RecipeId into g
let firstFile = g.FirstOrDefault()
select new
{
firstFile.Id,
firstFile.Path,
firstFile.RecipeId,
rec.Name,
rec.Description,
rec.Category,
rec.CookTime
}).ToList();
Update
since I don't use EF, I can't really confirm whether or not it handles nulls but I have been informed it doesn't you would have to remove nulls.
var UploadedFiles = (from rec in db.Recipes
join files in db.Files on rec.Id equals files.RecipeId into g
let firstFile = g.FirstOrDefault()
where firstFile != null
select new
{
firstFile.Id,
firstFile.Path,
firstFile.RecipeId,
rec.Name,
rec.Description,
rec.Category,
rec.CookTime
}).ToList();
You can try the following...
var UploadedFiles = (from rec in db.Recipes
from files in db.Files.FirstOrDefault(f => f.RecipeId == rec.Id)
select new
{
files.Id,
files.Path,
files.RecipeId,
rec.Name,
rec.Description,
rec.Category,
rec.CookTime
}).ToList();
return new JsonResult { Data = UploadedFiles, JsonRequestBehavior =
JsonRequestBehavior.AllowGet };

Not able to save multiple results into my table

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

Error in linq join query in MVC 4

I am trying this query:
public ActionResult Index()
{
var topics = from t in db.Topics
join subs in db.Subjects on t.SubID equals subs.SubID
join mems in db.Members on t.MemberID equals mems.MemberID
select new ViewModel
{
TopicID = t.TopicID,
TDate = t.TDate,
Title = t.Title,
FileName = t.FileName,
Displays = t.Displays,
Description = t.Description,
SubName = subs.SubName,
FLName = mems.FLName
};
return View(topics);
}
But it causes the following Error:
The entity or complex type 'MySiteModel.ViewModel' cannot be constructed in a LINQ to Entities query.
I have an Entitity Class with above fields.
What is the problem? ????
Try convert it to List<> first.
var topics = (from t in db.Topics
join subs in db.Subjects on t.SubID equals subs.SubID
join mems in db.Members on t.MemberID equals mems.MemberID
select new ViewModel
{
TopicID = t.TopicID,
TDate = t.TDate,
Title = t.Title,
FileName = t.FileName,
Displays = t.Displays,
Description = t.Description,
SubName = subs.SubName,
FLName = mems.FLName
}).ToList();
Hope it helps

sp_getProcedureColumns

I have tried to pass in the proc name into procedureNamePattern and the procedure seems to return all the metadata for all the procedures. I pass in a empty string and I get the same results.
The following is the code used:
using (AdsCommand command = new AdsCommand { CommandText = "sp_getProcedureColumns",
Connection = connection,
CommandType = CommandType.StoredProcedure })
{
AdsParameter param = new AdsParameter("#procedureNamePattern", DbType.String) {
Direction = ParameterDirection.Input, Value = originalProcedureName };
command.Parameters.Add(param);
AdsParameter param0 = new AdsParameter("#catalog", DbType.String) {
Direction = ParameterDirection.Input, Value = null };
command.Parameters.Add(param0);
AdsParameter param1 = new AdsParameter("#schemaPattern", DbType.String) {
Direction = ParameterDirection.Input, Value = null };
command.Parameters.Add(param1);
AdsParameter param2 = new AdsParameter("#columnNamePattern", DbType.String) {
Direction = ParameterDirection.Input, Value = null };
command.Parameters.Add(param2);
With stored procedures, you can use the DeriveParameters method. That might make it simpler. The following is an example:
AdsCommand cmd = conn.CreateCommand();
cmd.CommandText = "sp_getProcedureColumns";
cmd.CommandType = CommandType.StoredProcedure;
cmd.DeriveParameters();
cmd.Parameters["ProcedureNamePattern"].Value = "MyProcName";
AdsDataReader rdr = cmd.ExecuteReader();
If you do not call the DeriveParameters method, then the underlying SQL statement that is generated is produced directly from the provided parameters in the given order. That means you would need to provide the parameters in the order to match the procedure definition. In this case, the ProcedureNamePattern parameter needs to be 3rd. If you change the order of the cmd.Parameter.Add() calls, then your original example should work.

Resources