Kendo UI grid Batch Editing need to Display boolean value true(checkbox need to checked) false(checkbox need to uncheck) - asp.net-mvc-4

The Class Employee.cs is like that
public class Employee
{
public int EmployeeID;
public string Name;
}
The Class Order.cs is like that
public class Order
{
public int OrderID { get; set; }
public DateTime OrderDate { get; set; }
public string OrderDescription { get; set; }
public int EmployeeID { get; set; }
public bool checker { get; set; }
public bool Maker { get; set; }
public bool Supervisor { get; set; }
}
The Home Controller is like that
public class HomeController : Controller
{
public static List<Order> orderList = new List<Order> {
new Order {OrderID = 1, OrderDate = new DateTime(2012,8,1), EmployeeID = 1, OrderDescription = "Order Food",checker=true,Maker=true,Supervisor=true },
new Order {OrderID = 2, OrderDate = new DateTime(2012,8,1), EmployeeID = 2, OrderDescription = "Order Office Materials",checker=false,Maker=true,Supervisor=true },
new Order {OrderID = 3, OrderDate = new DateTime(2012,8,2), EmployeeID = 1, OrderDescription = "Order Production Materials",checker=true,Maker=true,Supervisor=true },
new Order {OrderID = 4, OrderDate = new DateTime(2012,8,3), EmployeeID = 4, OrderDescription = "Order Food",checker=true,Maker=true,Supervisor=true },
new Order {OrderID = 5, OrderDate = new DateTime(2012,8,4), EmployeeID = 3, OrderDescription = "Order Production Materials" ,checker=false,Maker=true,Supervisor=true},
new Order {OrderID = 6, OrderDate = new DateTime(2012,8,5), EmployeeID = 3, OrderDescription = "Order Production Materials" ,checker=true,Maker=true,Supervisor=true},
new Order {OrderID = 7, OrderDate = new DateTime(2012,8,5), EmployeeID = 4, OrderDescription = "Order Food", checker=true,Maker=true,Supervisor=true},
new Order {OrderID = 8, OrderDate = new DateTime(2012,8,6), EmployeeID = 1, OrderDescription = "Order Food", checker=true,Maker=true,Supervisor=true},
new Order {OrderID = 9, OrderDate = new DateTime(2012,8,6), EmployeeID = 1, OrderDescription = "Order Office Materials" ,checker=false,Maker=true,Supervisor=true},
new Order {OrderID = 10, OrderDate = new DateTime(2012,8,7), EmployeeID = 2, OrderDescription = "Order Production Materials",checker=true,Maker=true,Supervisor=true },
};
public static List<Employee> employeeList = new List<Employee> {
new Employee {EmployeeID = 1, Name = "Anrew"},
new Employee {EmployeeID = 2, Name = "John"},
new Employee {EmployeeID = 3, Name = "Peter"},
new Employee {EmployeeID = 4, Name = "Ivan"},
new Employee {EmployeeID = 5, Name = "Nancy"},
};
public ActionResult Index()
{
ViewData["employees"] = employeeList.Select(e => new {
EmployeeID = e.EmployeeID,
Name = e.Name
});
return View();
}
public ActionResult About()
{
return View();
}
public ActionResult Read([DataSourceRequest] DataSourceRequest request)
{
var allOrders = from orders in orderList
select new Order{
OrderID = orders.OrderID,
OrderDate = orders.OrderDate,
EmployeeID = orders.EmployeeID,
OrderDescription = orders.OrderDescription,
checker=orders.checker,
Maker=orders.Maker
};
return Json(allOrders.ToDataSourceResult(request));
}
public ActionResult Delete([DataSourceRequest] DataSourceRequest request, Order order)
{
if (order != null && ModelState.IsValid)
{
var target = orderList.Where(o => o.OrderID == order.OrderID).FirstOrDefault();
if (target != null)
{
orderList.Remove(target);
}
}
return Json(ModelState.ToDataSourceResult());
}
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Update([DataSourceRequest] DataSourceRequest request, Order order)
{
if (order != null && ModelState.IsValid)
{
var target = orderList.Where(o => o.OrderID == order.OrderID).FirstOrDefault();
if (target != null)
{
int targetIndex = orderList.IndexOf(target);
orderList[targetIndex].OrderDate = order.OrderDate;
orderList[targetIndex].EmployeeID = order.EmployeeID;
orderList[targetIndex].OrderDescription = order.OrderDescription;
orderList[targetIndex].checker = order.checker;
orderList[targetIndex].Maker = order.Maker;
orderList[targetIndex].Supervisor = order.Supervisor;
}
}
return Json(ModelState.ToDataSourceResult());
}
public ActionResult Create([DataSourceRequest] DataSourceRequest request, Order order)
{
order.OrderID = orderList[orderList.Count - 1].OrderID + 1;
orderList.Add(order);
return Json(new[] { order }.ToDataSourceResult(request, ModelState));
}
public ActionResult UpdateCreateDelete(
[Bind(Prefix = "updated")]List<Order> updatedOrders,
[Bind(Prefix = "new")]List<Order> newOrders,
[Bind(Prefix = "deleted")]List<Order> deletedOrders)
{
if (updatedOrders != null && updatedOrders.Count > 0)
{
for (int i = 0; i < updatedOrders.Count; i++)
{
var target = orderList.Where(o => o.OrderID == updatedOrders[i].OrderID).FirstOrDefault();
if (target != null)
{
int targetIndex = orderList.IndexOf(target);
orderList[targetIndex].OrderDate = updatedOrders[i].OrderDate;
orderList[targetIndex].EmployeeID = updatedOrders[i].EmployeeID;
orderList[targetIndex].OrderDescription = updatedOrders[i].OrderDescription;
orderList[targetIndex].checker = updatedOrders[i].checker;
orderList[targetIndex].Supervisor = updatedOrders[i].Supervisor;
orderList[targetIndex].Maker = updatedOrders[i].Maker;
}
}
}
if (newOrders != null && newOrders.Count > 0)
{
for (int i = 0; i < newOrders.Count; i++)
{
newOrders[i].OrderID = orderList[orderList.Count - 1].OrderID + 1;
orderList.Add(newOrders[i]);
}
}
if (deletedOrders != null && deletedOrders.Count > 0)
{
for (int i = 0; i < deletedOrders.Count; i++)
{
var target = orderList.Where(o => o.OrderID == deletedOrders[i].OrderID).FirstOrDefault();
if (target != null)
{
orderList.Remove(target);
}
}
}
return Json("Success!");
}
The html page Index.cshtml is like that
#(Html.Kendo().Grid<GridSyncChangesWithOneRequest.Models.Order>()
.Name("Grid")
.Columns(columns => {
columns.Bound(p => p.OrderID);
columns.ForeignKey(p => p.EmployeeID,(System.Collections.IEnumerable)ViewData["employees"], "EmployeeID", "Name");
columns.Bound(p => p.OrderDescription);
columns.Bound(p => p.Maker);
columns.Bound(p => p.checker);
//columns.Bound(p => p.checker).HeaderTemplate("Checker").ClientTemplate("<input type='checkbox' id='#= ID#,#= Name#' class='grid_checkbox'/>");
columns.Bound(p => p.Supervisor);
columns.Bound(p => p.OrderDate).Format("{0:d}");
columns.Command(c => {
c.Destroy();
});
})
.ToolBar(toolBar => toolBar.Create())
.Editable(editable => editable.Mode(GridEditMode.InCell))
.Pageable()
.Sortable()
.Scrollable()
.Filterable()
.DataSource(dataSource => dataSource
.Ajax()
.ServerOperation(false)
.Model(model => {
model.Id(p => p.OrderID);
model.Field(p => p.OrderDescription).Editable(false);
model.Field(p => p.EmployeeID).Editable(false);
model.Field(p => p.OrderID).Editable(false);
model.Field(p => p.Maker).Editable(false).DefaultValue(true);
model.Field(p => p.OrderDate).Editable(false);
})
.Create(create => create.Action("Create", "Home"))
.Destroy(destroy => destroy.Action("Delete", "Home"))
.Read(read => read.Action("Read", "Home"))
.Update(update => update.Action("Update", "Home"))
) )
Pressing the saveChanges will send all current changes to the
server:
<button onclick="sendData()">Save Changes</button>
<script>
function sendData() {
var grid = $("#Grid").data("kendoGrid"),
parameterMap = grid.dataSource.transport.parameterMap;
//get the new and the updated records
var currentData = grid.dataSource.data();
var updatedRecords = [];
var newRecords = [];
for (var i = 0; i < currentData.length; i++) {
if (currentData[i].isNew()) {
//this record is new
newRecords.push(currentData[i].toJSON());
} else if(currentData[i].dirty) {
updatedRecords.push(currentData[i].toJSON());
}
}
//this records are deleted
var deletedRecords = [];
for (var i = 0; i < grid.dataSource._destroyed.length; i++) {
deletedRecords.push(grid.dataSource._destroyed[i].toJSON());
}
var data = {};
$.extend(data, parameterMap({ updated: updatedRecords }), parameterMap({ deleted: deletedRecords }), parameterMap({ new: newRecords }));
$.ajax({
url: "/Home/UpdateCreateDelete",
data: data,
type: "POST",
error: function () {
//Handle the server errors using the approach from the previous example
},
success: function () {
alert("update on server is completed");
grid.dataSource._destroyed = [];
//refresh the grid - optional
grid.dataSource.read();
}
})
} </script>
Instead of True of False i need to show only checkBox while
Editing.Is there any possible solutions? !enter image description
here

Check the checker field for true and false in client template
columns.Bound(p=> p.checker).ClientTemplate("# if(checker==true){#" + "<input type='checkbox' checked='checked' />" + "#}else{#" + "<input type='checkbox' />" + "#}#");

You could either use this Telerik answer
or this from the documentation :
columns.Bound(p => p.Enabled).ClientTemplate(
"<input type='checkbox' value='#= ProductID #' " +
"# if (Enabled) { #" +
"checked='checked'" +
"# } #" +
"/>"
);

Related

PATCH in web API for Many to Many relationships using EF

I'm trying to remove a tag from a list of tags using a PATCH request. But while saving changes to the db context I get the following error:.
This the the PATCH code.
[HttpPatch("{id:int}/{field}", Name = "UpdateNote")]
[ProducesResponseType(StatusCodes.Status204NoContent)]
[ProducesResponseType(StatusCodes.Status404NotFound)]
public IActionResult UpdateNote(int id, string field, JsonPatchDocument<CreateNoteDTO> patchNoteDTO)
{
if (id == 0 || patchNoteDTO == null)
return BadRequest();
var note = _db.Notes.AsNoTracking().FirstOrDefault(u => u.ID == id);
if (note == null)
return NotFound();
CreateNoteDTO createNoteDTO = _mapper.Map<CreateNoteDTO>(note);
if (field.Equals("tags"))
{
var tags = _db.Tags.Where(u => u.Notes.Any(x => x.ID == note.ID)).AsNoTracking().ToList();
List<TagDTO> tagDTOs = new List<TagDTO>();
if (tags.Count > 0)
{
foreach (var tag in tags)
{
TagDTO tagDTO = _mapper.Map<TagDTO>(tag);
tagDTOs.Add(tagDTO);
}
}
createNoteDTO.Tags = tagDTOs;
}
patchNoteDTO.ApplyTo(createNoteDTO, ModelState);
if (!ModelState.IsValid)
return BadRequest(ModelState);
Note updateNote = _mapper.Map<Note>(createNoteDTO);
updateNote.ID = id;
updateNote.ChangedDate = DateTime.Now;
_db.Update(updateNote);
if (!field.ToLower().Equals("category"))
_db.Entry(updateNote).Property(u => u.FKCategory).IsModified = false;
_db.Entry(updateNote).Property(u => u.CreatedDate).IsModified = false;
_db.SaveChanges();
return NoContent();
}
My ApplicationDBContext looks like this:
public class ApplicationDbContext : DbContext
{
public ApplicationDbContext(DbContextOptions<ApplicationDbContext> options) : base(options)
{
}
public DbSet<Note> Notes { get; set; }
public DbSet<Category> Categories { get; set; }
public DbSet<Tag> Tags { get; set; }
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
//Write Fluent API configurations here
modelBuilder.Entity<Note>()
.HasOne(e => e.Category)
.WithMany(e => e.Notes)
.HasForeignKey(e => e.FKCategory)
.OnDelete(DeleteBehavior.Cascade);
modelBuilder.Entity<Note>()
.HasMany(n => n.Tags)
.WithMany(t => t.Notes)
.UsingEntity(j => j
.ToTable("NoteTag")
.HasData
(
new { NotesID = 1, TagsTagID = 1 },
new { NotesID = 2, TagsTagID = 2 }
));
modelBuilder.Entity<Category>().HasData
(
new Category
{
CategoryID = 1,
CategoryName = "testCategory1",
CreatedDate = DateTime.Now
},
new Category
{
CategoryID = 2,
CategoryName = "testCategory2",
CreatedDate = DateTime.Now
}
);
modelBuilder.Entity<Tag>().HasData
(
new Tag
{
TagID = 1,
TagName = "testTag1",
CreatedDate = DateTime.Now
},
new Tag
{
TagID = 2,
TagName = "testTag2",
CreatedDate = DateTime.Now
}
);
modelBuilder.Entity<Note>().HasData
(
new Note
{
ID = 1,
Title = "testTitle1",
Description = "testDescription1",
FKCategory = 1,
Deleted = false,
CreatedDate = DateTime.Now,
ChangedDate = DateTime.Now,
},
new Note
{
ID = 2,
Title = "testTitle2",
Description = "testDescription2",
FKCategory = 2,
Deleted = false,
CreatedDate = DateTime.Now,
ChangedDate = DateTime.Now,
}
);
}
}
Any suggestions?
Thanks in advance.
Initially I tried without the following if condition:
CreateNoteDTO createNoteDTO = _mapper.Map<CreateNoteDTO>(note);
if (field.Equals("tags"))
{
var tags = _db.Tags.Where(u => u.Notes.Any(x => x.ID == note.ID)).AsNoTracking().ToList();
List<TagDTO> tagDTOs = new List<TagDTO>();
if (tags.Count > 0)
{
foreach (var tag in tags)
{
TagDTO tagDTO = _mapper.Map<TagDTO>(tag);
tagDTOs.Add(tagDTO);
}
}
createNoteDTO.Tags = tagDTOs;
}
But I got a different error:
I wanted to remove a tag form the following object using a PATCH request:
Note Object

Display dynamic Navigation menu in asp.net core mvc layout page

I want to display dynamic menu in asp.net core mvc layout page. in my database table has menuid and parentid from that i want to display nested menus. if anyone have solution please help me and if any other method for this give an example.
Model is given below:
public class Menu
{
public int Id { get; set; }
public string MenuText { get; set; }
public string Url { get; set; }
public int? ParentId { get; set; }
public bool Active { get; set; }
public List<Menu> List { get; set; }
}
I want to use this in my layout class .How can i use this?
db_class Connstring = new db_class();
public void ProcessRequest(HttpContext context)
{
var user_id = Convert.ToString(context.Request["Id"]);
var str_company = Convert.ToString(context.Request["str_company"]);
List<Menu> listMenu = new List<Menu>();
string query = #"SELECT TOP (100) PERCENT dbo.Privilege.Name AS MenuText, dbo.[Right].[Add], dbo.[Right].Edit, dbo.[Right].[Delete], dbo.[Right].[view], dbo.[Right].Status AS Active, dbo.Privilege.URL AS url,
dbo.Privilege.ParentID AS ParentId, dbo.[Right].PrivilegeID AS menu_id, dbo.[Right].UserID, dbo.Company.Code, dbo.Company.Name, dbo.Privilege.ID
FROM dbo.Privilege INNER JOIN
dbo.[Right] ON dbo.Privilege.ID = dbo.[Right].PrivilegeID INNER JOIN
dbo.Module ON dbo.Privilege.ModuleID = dbo.Module.ID INNER JOIN
dbo.Department ON dbo.Module.DepartmentID = dbo.Department.ID INNER JOIN
dbo.Company ON dbo.Department.CompanyID = dbo.Company.ID
WHERE (dbo.[Right].Status = 1) AND (dbo.[Right].UserID = '" + user_id.Trim() + "') AND (dbo.Company.Code = '" + str_company.Trim() + "') AND (dbo.Privilege.Platform = 'Web') AND (dbo.Module.Platform = 'Web') OR (dbo.[Right].Status = 1) AND(dbo.[Right].UserID = '" + user_id.Trim() + "') AND(dbo.Privilege.ParentID IS NULL) ORDER BY dbo.Privilege.Priority, dbo.Privilege.ID";
using (SqlConnection con = Connstring.getcon)
{
SqlCommand cmd = new SqlCommand(query);
cmd.CommandType = CommandType.Text;
cmd.Connection = con;
con.Open();
SqlDataReader rdr = cmd.ExecuteReader();
while (rdr.Read())
{
Menu menu = new Menu();
menu.Id = Convert.ToInt32(rdr["menu_id"]);
menu.MenuText = rdr["MenuText"].ToString();
menu.ParentId = rdr["ParentId"] != DBNull.Value
? Convert.ToInt32(rdr["ParentId"]) : (int?)null;
menu.Url = rdr["url"].ToString();
menu.Active = Convert.ToBoolean(rdr["Active"]);
listMenu.Add(menu);
}
}
List<Menu> menuTree = GetMenuTree(listMenu, null);
JavaScriptSerializer js = new JavaScriptSerializer();
context.Response.Write(js.Serialize(menuTree));
}
public List<Menu> GetMenuTree(List<Menu> list, int? parent)
{
return list.Where(x => x.ParentId == parent).Select(x => new Menu
{
Id = x.Id,
MenuText = x.MenuText,
ParentId = x.ParentId,
Url = x.Url,
Active = x.Active,
List = GetMenuTree(list, x.Id)
}).ToList();
}
public bool IsReusable
{
get
{
return false;
}
}
Here is the javascript code :
var sl = 0;
function buildMenu(parent, items) {
$.each(items, function () {
//alert(this.MenuText);
//var icon = this.icon;
//if (icon == "") {
var icon = 'fa fa-circle-o';
//}
//------------------------------------//
if (this.List && this.List.length > 0) {
var pull_right = '</span><span class="pull-right-container"><i class="fa fa-angle-left pull-right"></i></span>';
icon = "glyphicon glyphicon-plus-sign";
}
else
pull_right = '';
//------------------------------------//
sl = sl + 1;
span_id = '';
if (this.Url != "") {
span_id = 'id="active_span_m' + sl + '"';
}
else {
span_id = '';
}
//-----------------------------------//
var li = $('<li id="m' + sl + '" onclick="set_menu_active(\'m' + sl + '\')" alt="' + this.Id + '" class="treeview"><i class="' + icon + '"></i><span ' + span_id + '>' + this.MenuText + pull_right + '</li>');
li.appendTo(parent);
if (this.List && this.List.length > 0) {
var ul = $('<ul class="treeview-menu menu-open"></ul>');
ul.appendTo(li);
buildMenu(ul, this.List);
}
});
//---------------Set Session---------------//
var str = $("<div />").append($("#menu").clone()).html();
sessionStorage.setItem("str_menu", str);
}
And Ajax:
$.ajax({
url: '../../../../../CDB/System/Common/Layout/Master/Permission.ashx',
method: 'get',
dataType: 'json',
data: { 'Id': u_s_id, 'str_company': str_company },
success: function (data) {
//alert(data);
buildMenu($('#menu'), data);
$('#menu').menu();
},
error: function (err) {
}
});
Output Image like as
Output image
Now i want to know process of use of this code in asp.net core mvc layout to get dynamic navigation menu

datediff with case statement in select query linq

select case statement in linq query.
Here is the query on sql:
select case when DATEDIFF(day,convert(varchar,Min([Order].CreatedOnUtc),101),convert(varchar,Max([Order].CreatedOnUtc),101)) = 0 then
Sum([Order].OrderSubtotal)
else
case when (DATEDIFF(day,convert(varchar,Min([Order].CreatedOnUtc),101),convert(varchar,Max([Order].CreatedOnUtc),101))/30) = 0 then Sum([Order].OrderSubtotal) else
Sum([Order].OrderSubtotal)/
(DATEDIFF(day,convert(varchar,Min([Order].CreatedOnUtc),101),convert(varchar,Max([Order].CreatedOnUtc),101))/30)
end
end as 'Account Value' from [order] where And Account.ID = #Act_ID
I am trying the code here:
var query = _orderRepository.Table;
query = query.Where(o => o.AccountId == accountId);
In query i am getting my value.
After query statement what should i write??
how do i write for case statement using linq???
#Manoj, may be the below code helps you. This sample C# project may solve the problem you have.
using System;
using System.Collections.Generic;
using System.Linq;
namespace DateDiffIssue
{
class Program
{
static void Main(string[] args)
{
// Preparing data
var data = new Order[] {
new Order { AccountID = 1, CreatedOnUtc = DateTime.Parse("1.01.2017 10:00"), OrderSubtotal = 100 },
new Order { AccountID = 1, CreatedOnUtc = DateTime.Parse("1.01.2017 12:00"), OrderSubtotal = 150 },
new Order { AccountID = 1, CreatedOnUtc = DateTime.Parse("1.01.2017 14:00"), OrderSubtotal = 150 }
};
// Selection
var selected = (from item in data
let accountData = data.Where(w => w.AccountID == 1)
let minDate = accountData.Min(m => m.CreatedOnUtc).Date
let maxDate = accountData.Where(w => w.AccountID == 1).Max(m => m.CreatedOnUtc).Date
let isSameDate = minDate == maxDate
let basedOn30Days = (maxDate - minDate).TotalDays / 30
let isInside30Days = (int)basedOn30Days == 0
let accountDataSum = accountData.Sum(s => s.OrderSubtotal)
select new
{
AccountValue = isSameDate ? accountDataSum :
isInside30Days ? accountDataSum :
accountDataSum / basedOn30Days
}).Distinct();
// Print each order
selected.ToList().ForEach(Console.WriteLine);
// Wait for key
Console.WriteLine("Please press key");
Console.ReadKey();
}
}
internal class Order
{
public int AccountID { get; set; }
public DateTime CreatedOnUtc { get; set; }
public int OrderSubtotal { get; set; }
}
}

How do I Reply a Comment So it can capture the comment

Please Guys, I have a forum and I want users to be able to reply comments so that the reply would appear with the comment.
This is what I have:
public ActionResult Quote(int? id)
{
var user = User.Identity.Name;
var userId = WebSecurity.CurrentUserId;
//var userId = db.UserProfiles.FirstOrDefault(x => x.UserName == user).UserId;
if (User.Identity.Name == null)
{
return RedirectToAction("Login", "Account");
}
if (id == null)
{
return RedirectToAction("topics", "forum");
}
//var p = db.Posts.FirstOrDefault(x => x.PostId == id.Value);
var post = db.Posts.Find(id.Value);
var comment = db.UserComments.FirstOrDefault();
var usercomment = db.UserComments.Find(comment.UserCommentId);
if (usercomment == null)
{
return RedirectToAction("topics");
}
return View(new Quote { UserId = WebSecurity.CurrentUserId, PostId = id.Value, UserCommentId = usercomment.UserCommentId });
}
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Quote(Quote quote, int id = 0)
{
if (ModelState.IsValid)
{
if (Request.Files.Count > 0)
{
System.Random randomInteger = new System.Random();
int genNumber = randomInteger.Next(1000000);
HttpPostedFileBase file = Request.Files[0];
if (file.ContentLength > 0 && file.ContentType.ToUpper().Contains("JPEG") || file.ContentType.ToUpper().Contains("PNG") || file.ContentType.ToUpper().Contains("JPG"))
{
WebImage img = new WebImage(file.InputStream);
if (img.Width > 500)
{
img.Resize(width: 500, height: 400, preserveAspectRatio: true, preventEnlarge: true);
}
if (img.Height > 700)
{
img.Resize(width: 500, height: 400, preserveAspectRatio: true, preventEnlarge: true);
}
string fileName = Path.Combine(Server.MapPath("~/Uploads/"), Path.GetFileName(genNumber + file.FileName));
img.Save(fileName);
if (fileName == null)
{
ViewBag.image = "True";
}
quote.QuoteFile = fileName;
}
}
var user = WebSecurity.CurrentUserId;
//var userId = db.UserProfiles.FirstOrDefault(a => a.UserId == user);
db.Quotes.Add(quote);
quote.QuotedBy = User.Identity.Name;
var post = db.Quotes.Include(f => f.Posts).Where(x=>x.UserCommentId == quote.UserCommentId).OrderByDescending(s => s.QuoteId);
quote.DateQuoted = DateTime.Now;
db.SaveChanges();
return RedirectToAction("topics", "forum", new { id = quote.PostId});
}
return View(quote);
}
public ActionResult _Quote(int id = 0)
{
//var comment = db.UserComments.FirstOrDefault(x => x.PostId == id);
var user = WebSecurity.CurrentUserId;
var comments = db.Quotes.Where(x => x.PostId == id).ToList();
//var quotes = db.UserComments.Where(x => x.PostId == id).ToList();
var p = new UserComment();
p.DateUserCommented = DateTime.Now;
DateTime dt = Convert.ToDateTime(p.DateUserCommented);
string strDate = dt.ToString("dd MMMM yyyy - hh:mm tt");
ViewBag.p = strDate;
ViewBag.data = comments;
return PartialView(comments);
}

nhibernate: select parents and newest child

I have the following entities
public class Vehicle
{
public virtual string InternalNumber { get; set; }
public virtual IList<VehicleDriverHistory> DriverHistory { get; set; }
}
public class VehicleDriverHistory : HistoryEntity
{
public virtual Vehicle Vehicle { get; set; }
public virtual DriverPerson Driver { get; set; }
public virtual DateTime Date { get; set; }
}
Now I need to select every Vehicle and, if present, the newest VehicleDriverHistory-Entry according to "Date".
But I'm kinda struggling, I have no problem doing it in sql, but failed in nhibernate so far.
What I have so far:
VehicleDriverHistory vdHistory = null;
VehicleDriverHistory vdHistory2 = null;
q.Left.JoinAlias(x => x.DriverHistory, () => vdHistory);
q.Left.JoinAlias(x => x.DriverHistory, () => vdHistory2).Where(x => vdHistory2.Date > vdHistory.Date);
q.Where(x => vdHistory2.Id == null);
This doesn't work and it was just my attempt to "translate" the sql query (which yields the correct data) to nhibernate.
So, how would I select parents and the newest child (or none if none is present)
Thanks
UPDATE
With Firos help I ended up with the following:
VehicleDriverHistory historyAlias = null;
var maxDateQuery = QueryOver.Of<VehicleDriverHistory>()
.Where(h => h.Vehicle == historyAlias.Vehicle)
.Select(Projections.Max<VehicleDriverHistory>(h => h.Date));
var vehiclesWithEntry = DataSession.Current.QueryOver(() => historyAlias)
.WithSubquery.WhereProperty(h => h.Date).Eq(maxDateQuery)
.Fetch(h => h.Vehicle).Eager
.Future();
Vehicle VehicleAlias = null;
var vehiclesWithoutEntry = DataSession.Current.QueryOver<Vehicle>(() => VehicleAlias)
.WithSubquery
.WhereNotExists(QueryOver.Of<VehicleDriverHistory>()
.Where(x => x.Vehicle.Id == VehicleAlias.Id).Select(x => x.Id))
.Future();
return vehiclesWithEntry.Select(h => new PairDTO { Vehicle = h.Vehicle, NewestHistoryEntry = h }).Concat(vehiclesWithoutEntry.Select(v => new PairDTO { Vehicle = v })).ToList();
I had to replace the Any() statement in vehclesWithoutEntry with a subquery-clause because it raised an exception.
some other idea using Futures to make only one roundtrip
VehicleDriverHistory historyAlias = null;
var maxDateQuery = QueryOver.Of<VehicleDriverHistory>()
.Where(h => h.Vehicle == historyAlias.Vehicle)
.Select(Projections.Max<VehicleDriverHistory>(h => h.Date));
var vehiclesWithEntry = session.QueryOver(() => historyAlias)
.WithSubquery.WhereProperty(h => h.Date).Eq(maxDateQuery)
.Fetch(h => h.Vehicle).Eager
.Select(h => new PairDTO { Vehicle = h.Vehicle, NewestHistoryEntry = h })
.Future<PairDTO>();
var vehiclesWithoutEntry = session.QueryOver<Vehicle>()
.Where(v => !v.DriverHistory.Any())
.Select(v => new PairDTO{ Vehicle = v })
.Future<PairDTO>();
return vehiclesWithoutEntry.Concat(vehiclesWithEntry); // .ToList() if immediate executing is required
Update: i can not reproduce the exception but you could try this
VehicleDriverHistory historyAlias = null;
var maxDateQuery = QueryOver.Of<VehicleDriverHistory>()
.Where(h => h.Vehicle == historyAlias.Vehicle)
.Select(Projections.Max<VehicleDriverHistory>(h => h.Date));
var vehiclesWithEntry = session.QueryOver(() => historyAlias)
.WithSubquery.WhereProperty(h => h.Date).Eq(maxDateQuery)
.Fetch(h => h.Vehicle).Eager
.Future();
var vehiclesWithoutEntry = session.QueryOver<Vehicle>()
.Where(v => !v.DriverHistory.Any())
.Select(v => new PairDTO{ Vehicle = v })
.Future<PairDTO>();
return vehiclesWithoutEntry.Select(h => new PairDTO { Vehicle = h.Vehicle, NewestHistoryEntry = h }).Concat(vehiclesWithEntry);