How to use normal sql in ASP.NET MVC without EF? - sql

I have this class using linq to sql, how do I implement the same by using normal sql in ASP.NET MVC 3 without use EF?
public ActionResult Index()
{
var List = (from c in db.OFFICE
join s in db.CAMPUS_UNIVERSITY on c.IdCampus equals s.IdCampus
join u in db.UNIVERSITY on s.IdUniversity equals u.IdUniversity
select u).ToList();
return View(List);
}

This is just a sample.(Tested & working ).That is y i am keeping the GetUniversities method inside the controller class . I suggest you to move the GetUniversities method to some service layer so that many UI/Controllers can use that.
public ActionResult Index()
{
var items= GetUniversities();
return View(items);
}
private List<DataRow> GetUniversities()
{
List<DataRow> list=null;
string srtQry = "SELECT U.* FROM Office O INNER JOIN
CampusUniversity CU ON O.IdCampus equals CU.IdCampus
INNER JOIN UNIVERSITY U ON U.IdUniversity=CU.IdUniversity";
string connString = "Database=yourDB;Server=yourServer;UID=user;PWD=password;";
using (SqlConnection conn = new SqlConnection(connString))
{
string strQry = "";
using(SqlCommand objCommand = new SqlCommand(srtQry, conn))
{
objCommand.CommandType = CommandType.Text;
DataTable dt = new DataTable();
SqlDataAdapter adp = new SqlDataAdapter(objCommand);
conn.Open();
adp.Fill(dt);
if (dt != null)
{
list = dt.AsEnumerable().ToList();
}
}
}
return list;
}
Keep in mind that the GetCustomers method returns a List of DataRows. Not your custom domain entities. Entity framework is giving you the list of Domain Entities. So in the custom SQL case, you need to map the Data Row to an instance of your custom object yourself.
With LINQ, You can convert the List of DataRow to your custom objects like this
public ActionResult Index()
{
var items= GetCustomers();
var newItems = (from p in items
select new
{
Name= p.Field<String>("Name"),
CampusName= p.Field<String>("CampusName")
}).ToList();
return View(newItems);
}
This will give you a list of anonymous type which has 2 properties, Name and CampusName. Assuming Name and CampusName are 2 columns present in the result of your query.
EDIT2 : As per the Comment, To List these data in a view, Create a view called Index inside your controller( where we wrote this action methods) folder under Views Folder.We need to make it a strongly typed view. But Wait! What type are we going to pass to the view ?
Our result is annonymous type. So We will create a ViewModel in this case and instead of annonymous, We will return a List of the ViewModel.
public class UniversityViewModel
{
public string UniversityName { set;get;}
public string CampusName { set;get;}
}
Now we will update the code in our Index action like this.
var newItems = (from p in items
select new UserViewModel
{
UniversityName = p.Field<String>("Name"),
CampusName = p.Field<String>("CampusName")
}).ToList();
The only change is we now mentioned a type here. So the output is no more annonymous type. But known type.
Let us go back to our View and write code like this.
#model IEnumerable<SO_MVC.Models.UserViewModel>
#foreach (var item in Model)
{
<p>#item .UniversityName #item.CampusName</p>
}
This view is strongly typed to a collection of our ViewModel. As usual we are looping thru that and displaying. This should work fine. It is Tested.

This is not necessarily MVC specific. You could do the same thing in Webforms or Windows Forms, etc. Take a look at using ADO.NET for your queries or Dapper.

SELECT
u.*
FROM
OFFICE c
INNER JOIN CAMPUS_UNIVERSITY s ON c.IdCampus = s.IdCampus
INNER JOIN UNIVERSITY u ON s.IdUniversity = u.IdUniversity

Related

ViewModel as source type for new object with Automapper?

Is it possible to use an ViewModel object (ViewModels.Combined) that holds two Lists (domains and reginfos) as a source type for Automapper?
Sample source code:
public ActionResult Index()
{
var domains = from x in unitofwork.DomainRepository.Get()
select x;
var reginfos = from x in unitofwork.RegInfoRepository.Get()
select x;
var combined = new Combined(domains, reginfos);
Mapper.CreateMap<Combined, Home>();
Home[] something = Mapper.Map<Combined[], Home[]>(combined); // throws error
return View();
}
The ideal situation would be to flatten ViewModels.Combined and be able to use ex. Model.domains.FullName.
Thanks in advance and sorry for mixing up term. I'm pretty new to mvc and .net

How to get a single value from db using Fluent Hibernate

I'm new to Fluent Hibernate And I'm stuck with a problem I want to get the email id of a user by using his user name means I want to implement the following code using fluent Hibernate
Select emailId from Table where username="User"
I tried the following code but its not give me what i want
public string ForgetPassword(string user)
{
var factory = CreateSessionFactory();
using (var session = factory.OpenSession())
{
var getEmail = session.Query<ClsAccountBL>()
Select(u => u.Email).Where(u => u.User == user).ToString();
return getMail;
}
}
Please help me to solve this
Instead of .ToString() use FirstOrDefault(). The LINQ does not return "single" element.

Petapoco: How to databind gridview using join from two tables?

I dont want to do using a custom class.
var q = db.Query<dynamic>(query); //This does not work
query has joins and custom created columns from multiple tables.
You can check the PetaPoco.cs "ExecuteReader" method to see if it looks something like this(see code below):
my file did not have any code in the function so I model it after Execute scalar method.
this will return a generic DataTable that is perfectly bindable to datagrid.
however keep in mind that to make any changes to the data you will need to implement
your own CRUD methods as the resulting DataTable is readonly.
//Execute Reader
public DataTable ExecuteReader(string sql, params object[] args)
{
try
{
OpenSharedConnection();
try
{
using (var cmd = CreateCommand(_sharedConnection, sql, args))
{
var val = cmd.ExecuteReader();
OnExecutedCommand(cmd);
var dt = new DataTable();
dt.Load(val);
return dt; //(T)Convert.ChangeType(val, typeof(T));
}
}
finally
{
CloseSharedConnection();
}
}
catch (Exception x)
{
OnException(x);
throw;
}
}
public DataTable ExecuteReader(Sql sql)
{
return ExecuteReader(sql.SQL, sql.Arguments);
}
Create a class that contains the fields from the two tables you want to display in the grid.
Populate your query with a SQL statement that joins the tables and returns the columns you need.
Then
var q=db.Query<YourClassName>.Query(query)
should work.
You can create a database view, and then the T4 templates will automatically generate the class for that. You need to add
IncludeViews = true;
to Database.tt

Handle navigation properties when adding new object to entity model

I have the following data model:
I am writing a WCF service that needs to support adding new Report:
public bool CreateNewReport(Report report)
{
MyEntities context = new MyEntities();
context.AddToReports(Report);
context.SaveChanges();
}
So my method gets a report object that was made on the client and adds it to the database throught the data context. (all of the members are included in the DataContract)
My question is regarding navigation properties.
Do the client also needs to create a user object and put it in the new report object before sending it ?
What is the best way to approach this ? one way i think of is adding a UserId field in the ReportEntity
when a new report is inserted, how do i update the UserEntity Report nav property that with the new Report ?
Thanks.
If you import your database, generate navigation properties (the properties in your picture) AND foreign id properties (then you have for example an User and UserID property in your report class). This way you can set the UserID in your client and send it to the server and add it with AddToReports... If you send the whole user object you have to attach it to the entity context otherwise the user will be created once again...
Attach the referenced user: (but it's better to send the user only by id)
public bool CreateNewReport(Report report)
{
using (MyEntities context = new MyEntities())
{
context.AddToReports(Report);
context.Users.Attach(report.User);
context.SaveChanges();
}
}
To change the report of a user:
public bool ChangeUserToNewReport(int userid, Report newReport)
{
using (MyEntities context = new MyEntities())
{
var user = context.Users.Single(u => u.ID = userid);
user.Report = newReport;
context.SaveChanges();
}
}
For an existing report:
public bool ChangeUserReport(int userid, Report existingReport)
{
using (MyEntities context = new MyEntities())
{
context.Reports.Attach(existingReport);
var user = context.Users.Single(u => u.ID = userid);
user.Report = existingReport;
context.SaveChanges();
}
}
This is a sample how your model should look like. Double click on the association line to open the dialog. You can see that the Person and PersonID properties are the same. If you create your model like this, VS should generate the correct SQL.

Loading jqgrid from query with multiple joins

I am trying to load a sortable jqgrid 3.5 from a query with multiple joins in it and having much difficulty as I am a novice with both Linq and jqgrid. In order to allow for sorting I first was attempting to load it using dynamic SQL.
Since I am pulling columns from multiple tables I assume my return will be a class object which I will populate (or will it be a table). How can I return a IQueryable custom class object when using dynamic SQL with multiple .JOIN clauses. If this is impossible how do I return IQueryable data from a stored procedure call. It is easy to create dynamic SQL in the stored procedure - I am unsure how to load my grid with it however.
Sorry if this is all over the place but I can't seem to find a way. If you can recommend the most straight forward way to load my sortable grid from a query which has multiple joins in I am much appreciated.
My controller code:
public ActionResult GridData(string sidx, string sord, int page, int rows)
{
EquipTrak eqt = new EquipTrak();
var equipment = eqt.GetGridEquipment(sidx, sord);
var dataJson = new
{
total = 10000,
page = 1,
records = 10000,
rows = (from e in equipment
select new
{
equip_id = e.equip_id,
cell = new string[] {
e.equip_id,
e.equipType,
e.makeType,
String.Format("{0:MM/dd/yyyy}", e.serv_due_dt)
}
}).ToArray()
};
return Json(dataJson);
}
}
my class code (incomplete):
namespace ULS_Site.Models
{
public class EquipTrak
{
uls_dbDataContext ulsDB = new uls_dbDataContext();
public IQueryable<equipmentCls> GetGridEquipment(string sidx, string sord)
{
try
{
return
Not sure if this is the best or worst solution but I used SQL Server views to handle all the joining required. I could then use .Orderby and .Where against the view which was in my data context.