I have created a viewmodel class for my custom page. I have a stored procedure which returns the DataTable(ORM tool). I cannot change this procedure. But I would like display the records from the stored procedure on View List. How can I display the values from the datatable in the List View? I appreciate any help.
Thanks,
public class CreateViewModel
{
[Required]
public DateTime StartDate {get; set;}
[Required]
[StringLength(250, ErrorMessage = "Details must be less than 250 characters")]
public string Details { get; set; }
}
The main way of doing it would be reading out the column values from each row of the datatable into the view model instance. This is regular DataTable access way. This should be done in your service layer called from your controller action.
If you can't change the stored proc, but are not tied to a DataTable then if you execute the SqlCommand to return a SqlReader. Then you can access the data with the following code (something like):
var list = new List<MyViewData>();
while(reader.Read())
{
var model = new MyViewData();
model.Property = reader.GetString(reader.GetOrdinal("ColumnName"));
// .. etc..
list.Add(model);
}
return list;
This accesses the recordset returned from the stored proc.
You can then set your view's model property as an IEnumerable then you can access each of the instances with a foreach over the model in the view.
Hope this helps.
Related
The stored procedure output gives me an integer value. I need to pass that value to the view page and increment it.
Controller:
var OrderId = db.USP_SEL_LAST_ORDERID();
ViewData["OrderId"] = (OrderId);
View:
var orderid = int.Parse(#ViewBag.OrderId);
Error:
The best overloaded method match for 'int.Parse(string)' has some invalid arguments
#Wheels73's answer is almost right, however you need to know that stored procedure method returns data from DbContext in form of result set, even it has only single value. You can use either FirstOrDefault() or FirstOrDefault<int>() method to ensure it returns int:
Controller
var OrderId = db.USP_SEL_LAST_ORDERID().FirstOrDefault();
ViewData["OrderId"] = OrderId; // ensure this is an integer
View
var orderid = int.Parse(#ViewBag.OrderId.ToString());
Note that System.Data.Entity.Core.Objects.ObjectResult<T> can have multiple values (with different data types), hence it is possible to ask for first int to get SP result. Also, better to use strongly-typed viewmodel class with int property rather than dynamic ViewBag or ViewData:
Model
public class ViewModel
{
public int OrderId { get; set; }
}
Controller
public ActionResult ActionName()
{
var model = new ViewModel();
var OrderId = db.USP_SEL_LAST_ORDERID().FirstOrDefault();
model.OrderId = OrderId;
// returns entire viewmodel to view, 'int.Parse' conversion not required
return View(model);
}
Similar issue:
consume int result returned from stored procedure in MVC4
How to handle ObjectResult in Entity Framework 4
See below.
var orderid = int.Parse(#ViewBag.OrderId.ToString());
Thanks
I want to get specific column of the table but I get this error
The data reader is incompatible with the specified 'NewsDatabaseModel.News'. A member of the type, 'NewsSubject', does not have a corresponding column in the data reader with the same name.
I don't want to use stored procedure via the model I just want to call it.
Here is my code
var NewsList = db.Database.SqlQuery<News_Application.News>("[dbo].[GetAllNews]").ToList();
return View("NewsList");
SQL:
CREATE PROCEDURE GetAllNews
AS
BEGIN
SELECT NewsId, NewsTitle
FROM News
END
Your News_Application.News class must have the same named properties as the returned select from your stored procedure, and all properties must exist in the select sentence.
Since you only want a single column, create a ViewModel class and bind your procedure to it like this:
public class NewsViewModel
{
public int NewsId { get; set;}
public string NewsTitle { get; set; }
}
and bind your procedure
var NewsList = db.Database.SqlQuery<NewsViewModel>("[dbo].[GetAllNews]").ToList();
[EDIT]
For returning an anonymous object, do like this:
var NewsList = db.Database.SqlQuery<NewsViewModel>("[dbo].[GetAllNews]").Select(x => new { x.NewsId, x.NewsTitle }).ToList();
This will return an object that has no class and the properties you need.
Either way, I believe you should reconsider your design. There shouldn't be the need to use a stored procedure for executing such a simple query.
Lets suppose your entity's name is News.
This would suffice:
var NewsList = db.News.Select(x => new { x.NewsId, x.NewsTitle }).ToList();
I'll recommend this website for getting you up to speed with entity framework: http://www.entityframeworktutorial.net/EntityFramework5/entity-framework5-introduction.aspx
I've created a Dictionary like
Dictionary<Department,bool> dict= new Dictionary<Department,bool>();
here Department is a class and I have Id,Name and Code for the departments. And in the bool am sending whether the person is HOD or not.
Am adding the records to this Dictionary like
dict.Add(department,chkHOD.checked);
here the records are successfully added to the Dictionary and after this am binding the Dictionary to a GridView like
gridDept.Datasource=dict;
gridDept.Databind();
now the inserted records are displayed fine in the gridview. After this am storing this records in the 'StaffDepartments' table in my database. I have 3 columns in the 'Staffdepartments' table
1.StaffId(PK - has link with the Staff table)
2.DepartmentId(PK - has link with the Department table)
3.IsHOD.
here the records are stored fine in the database.No problem in adding the records into the database.
I have some questions here
*1.How can check whether the DepartmentId is already there in the Dictionary before adding to it.
2.When am editing the staff detail how can I delete the Selected Department from the Dictionary by checking the checkbox in Gridview rows.(here the records are coming from the database, so when I click delete button the records should be deleted in the database as well)*
if its a List instead of Dictionary, I can get the DepartmentId by
int departmentId = (int)gridDept.DataKeys[row.RowIndex].Values["DepartmentId"];
but in Dictionary i dunno how to do the same with Key and Value pairs....can anyone help me here.
How can check whether the DepartmentId is already there in the
Dictionary before adding to it.
You could use this:
if (!dict.Keys.Any(d => d.DepartmentId == department.DepartmentId))
dict.Add(department,chkHOD.checked);
But something is wrong here. If your real key is the DepartmentId and not the Department (object identity) you should make it the key in the dictionary. For example, you could define a helper class:
public class DepartmentBindingHelper
{
public int DepartmentId { get; set; }
public Department Department { get; set; }
public bool Checked { get; set; }
}
An then define a dictionary like this:
var dict = new Dictionary<int, DepartmentBindingHelper>();
And add the objects this way to the dictionary:
if (!dict.ContainsKey(department.DepartmentId))
dict.Add(department.DepartmentId, new DepartmentBindingHelper
{
DepartmentId = department.DepartmentId,
Department = department,
Checked = chkHOD.checked
});
Then you can bind only the value collection to the grid:
gridDept.Datasource = dict.Values;// it's an IEnumerable<DepartmentBindingHelper>
gridDept.Databind();
And your code to retrieve the DepartmentId from a row would work without changes:
int departmentId = (int)gridDept.DataKeys[row.RowIndex].Values["DepartmentId"];
I'm trying to use Linq in a webservice that returns a data from a query. As
the data return from Linq to Sql is IEnumerable and it's not possible to
easily get a Dataset.what is the best format to return data?
DataClassesDataContext Dac = new DataClassesDataContext();
Dac.Connection.ConnectionString = ConfigurationManager.ConnectionStrings["ConnectionCs"].ConnectionString;
var query = from record in Dac.RetrieveWorkshops(WorkshopCode, Name) select record;
Web-service proxies instantiate collections as arrays, so I've gotten into the habit of defining 'data transfer objects' and returning IEnumerable's of those DTO's. In your case, You could define a WorkshopDTO object which contained only the public properties you wanted to return and have your LINQ query construct them based on each record it reads. Then your client-proxy will see an array of WorkshopDTO's to manipulate.
You can populate your data into an object and return a list of that object in Web Service.
Example:
public class WorkshopEntity
{
string Name { get; set; }
string Location { get; set; }
}
List<WorkshopEntity> workshopList = (from record in Dac.RetrieveWorkshops(WorkshopCode, Name) select new WorkshopEntity { Name=record.name, Location=record.Location }).ToList();
return query.ToArray();
but remember to add [Serializable] Attribiute at top of your WorkshopEntity class.
if your have complex type properties in WorkshopEntity inform me because you should do more.
This question, although similar to others, doesn't seem to be a duplicate. If it is, please clarify and I will be happy to merge.
I want to bind to a writable DataGridView using a linq-to-entities query containing a join. The model is as follows:
The denormalized DataGridView should be bound like so:
The following code binds but results in a readonly DataGridView because the linq-to-entities query returns an anonymous type (see this post). I'm at an impasse because I think I need the anonymous type to do the denormalization.
var query = from t in iDictionaryContext.DisplayTexts
from l in iDictionaryContext.Languages
where
t.LanguageID == l.LanguageID
select new
{
Key = t.DisplayKey,
Text = t.DisplayText1,
Language = l.LanguageName
};
I also tried the solution suggested here but it seems to apply to linq-to-sql but not to linq-to-entities. When setting the bindingsource.datasource to the linq-to-entities query, an exception is thrown reading "Only parameterless constructors and initializers are supported in LINQ to Entities."
Thank you for your advice,
Tim
Just define presentation type like that. You don't have to pass objects in constructor:
public class LanguageDisplayTextPresentation
{
public int Key { get; set; }
public string Text { get; set; }
public string Language { get; set; }
}
and then
var query = from t in iDictionaryContext.DisplayTexts
from l in iDictionaryContext.Languages
where
t.LanguageID == l.LanguageID
select new LanguageDisplayTextPresentation
{
Key = t.DisplayKey,
Text = t.DisplayText1,
Language = l.LanguageName
};