assign nullable objects for returning IQueryable - asp.net-mvc

I am returning IQueryable<Customer> to the other method for some querying operations. The return method looks like:
return from cust in _dbCustList
select new Customer
{
CustomerId = cust.Customer_Id,
FirstName= cust.First_Name,
LastName= cust.Last_Name,
DOB= cust.Date_Of_Birth,
LoginTime = cust.Login_Time ?? new TimeSpan(0, 0, 0);
};
In the above result, cust.Login_Time is nullable property.
When i try to query the above result, it throws an error:
Method 'System.TimeSpan GetTimeSpan(System.Nullable`1[System.TimeSpan])' has no supported translation to SQL.
How to solve this error?

I would query into an anonymous type and then map the result to your business object in-memory:
var q = from cust in _dbCustList
select new
{
cust.Customer_Id,
cust.First_Name,
cust.Last_Name,
cust.Date_Of_Birth,
cust.Login_Time
};
return from cust in q.AsEnumerable()
select new Customer
{
CustomerId = cust.Customer_Id,
FirstName= cust.First_Name,
LastName= cust.Last_Name,
DOB= cust.Date_Of_Birth,
LoginTime = cust.Login_Time ?? TimeSpan.Zero;
};

Why do you use the null- check?
When you remove the null check the written query gets translated into a SQL query and will be executed. Now you have the result you can do any magic you want...

Related

MVC Query Result no accept null values

enter image description here Function ListarTipoMascotas() As JsonResult
Dim db As New LQTestDataContext
Dim Listado = From tipomascota In db.TipoMascotas
Where tipomascota.BHABILITADO = 1
Select New With {
.Id = tipomascota.IIDTIPOMASCOTA,
.Nombre = tipomascota.NOMBRE
}
Return New JsonResult With {.Data = Listado,
.JsonRequestBehavior = JsonRequestBehavior.AllowGet
}
End Function
This is my function in VB. MVC , is work fine, but when I have null values the LINQ sent a error.
I'm working with LINQ for my conexion database,
My question is, how I can to do, to this result I can return null values without any problem.
Thank you. I read you.

Search database depending on chosen search criteria

I'm following a YouTube series which teachs ASP.NET MVC. In the tutorial the teacher shows how to make a simple search functionality however in my case it's different.
I have search criteria: Studies (Dropdown), Country (Dropdown), Status (Dropdown) and Keyword (Input).
My question is how do I query the database to show the results depending on the search criteria that was chosen?
To be more clear:
If the User has chosen Studies and Country only then the code should use values from Studies and Country to search the respective database column.
Click here for the UI Design
Table: Students
[StudentID] INT IDENTITY (1, 1) NOT NULL,
[StudentName] VARCHAR (50) NOT NULL,
[StudentStudiesID] INT NOT NULL,
[StudentCountry] VARCHAR (50) NOT NULL,
[StudentCity] VARCHAR (50) NOT NULL,
[StudentStatus] VARCHAR (50) NOT NULL,
CONSTRAINT [PK_Students] PRIMARY KEY CLUSTERED ([StudentID] ASC),
CONSTRAINT [FK_Students_Studies] FOREIGN KEY ([StudentStudiesID]) REFERENCES [dbo].[Studies] ([StudiesID])
SearchController.cs
public class SearchController : Controller
{
public ActionResult Index()
{
DatabaseEntitiesModel db = new DatabaseEntitiesModel();
int Studies;
int.TryParse(Request.QueryString["Studies"], out Studies);
var Country = Request.QueryString["Country"];
var Status = Request.QueryString["Status"];
var Keyword = Request.QueryString["Keyword"];
IQueryable <Student> SearchQuery = db.Students;
List<SearchViewModel> SVM = SearchQuery.Select(x => new SearchViewModel
{
StudentID = x.StudentID,
StudentName = x.StudentName,
StudentCountry = x.StudentCountry,
StudentCity = x.StudentCity,
StudiesName = x.Study.StudiesName,
StudentStatus = x.StudentStatus
}).OrderByDescending(x => x.StudentID).ToList();
return View( SVM );
}
}
Reuse SearchQuery (items are lazy-loaded, until you call ToList()) and add as many specific Where() clauses/calls as you need:
// the type (IQueryable<Student>) should be defined explicitly
// details: https://stackoverflow.com/questions/21969154/cannot-implicitly-convert-type-system-linq-iqueryable-to-system-data-entity-d
IQueryable<Student> query = db.Students;
if(viewModel.Filter1 != null) {
query = query.Where(i => i.SomeStudentProperty1 == viewModel.Filter1);
}
if(viewModel.Filter2 != null) {
query = query.Where(i => i.SomeStudentProperty2 == viewModel.Filter2);
}
var result = query.ToList();
The easiest way to do this would be to test each condition and if it meets what you want, add a Where clause. Something like this:
int.TryParse(Request.QueryString["Studies"], out Studies);
var Country = Request.QueryString["Country"];
var Status = Request.QueryString["Status"];
var Keyword = Request.QueryString["Keyword"];
IQueryable<Student> SearchQuery = db.Students;
if(Studies > 0)
{
SearchQuery = SearchQuery.Where(s => s.StudiesID == Studies);
}
if(!string.IsNullOrEmpty(Country))
{
SearchQuery = SearchQuery.Where(s => s.StudentCountry == Country);
}
...More conditions can go here
Because of Lazy Loading, the actual query isn't executed until you call .ToList(), or iterate over the collection. Hopefully, this gets you started on the right track.
Edit
In my haste, I changed your IQueryable to a var. Fixed.
Also, as Erik pointed out, using Request.QueryString is not the way to go. You'll instead want to pass these values in to the action method. So, something like:
public ActionResult Index(int studies, string status, string country, string keyword)

MVC Enity Framework get KEY attribute from table

I am trying to extract the [key] value from a table.
This is for a logging method which looks like this:
private List<Log> GetAuditRecordsForChange(DbEntityEntry dbEntry, string userId)
{
List<Log> result = new List<Log>();
DateTime changeTime = DateTime.Now;
// Get the Table() attribute, if one exists
TableAttribute tableAttr = dbEntry.Entity.GetType().GetCustomAttributes(typeof(TableAttribute), false).SingleOrDefault() as TableAttribute;
// Get table name (if it has a Table attribute, use that, otherwise get the pluralized name)
string tableName = tableAttr != null ? tableAttr.Name : dbEntry.Entity.GetType().Name;
// Get primary key value
string keyName = dbEntry.Entity.GetType().GetProperties().Single(p => p.GetCustomAttributes(typeof(KeyAttribute), false).Count() > 0).Name;
if (dbEntry.State == EntityState.Added)
{
result.Add(new Log()
{
LogID = Guid.NewGuid(),
EventType = "A", // Added
TableName = tableName,
RecordID = dbEntry.CurrentValues.GetValue<object>(keyName).ToString(),
ColumnName = "*ALL",
NewValue = (dbEntry.CurrentValues.ToObject() is IDescribableEntity) ? (dbEntry.CurrentValues.ToObject() as IDescribableEntity).Describe() : dbEntry.CurrentValues.ToObject().ToString(),
Created_by = userId,
Created_date = changeTime
}
);
}
The problem is to get the RecordID when a Record is added, when it get deleted or modified it works. (The code to get it is the same)
When I debug I also see that it has the KeyAttribute in the CustomAttributes base but not sure why it always shows up as 0.
I can debug more if needed
After savechanges you can fetch the newly created key. (Guess the key is generated automatically inserting a new record).
for me you have several solutions.
first solution:
enlist added entity from the context
SaveChanges
enumerate the enlisted entities to add log
SaveChanges
the problem (or not) here is that the business and the logging are not in the same transaction.
antother problem, depending on the implementation, is to prevent loging of log of log of log... This can be donne by filtering entities by typeName for example.
other solution:
add and ICollection<Log> to your entities.
the problem here is to unify the logs:
inheritance of entity, or
several log tables + a view
...
other solution
use trigger at database level
other solution
..., use cdc if you have Sql Server Enterprise Edition

Cannot compare in linq

I am trying to get the result of the user logged in but receiving this error :
"Cannot compare elements of type 'System.Linq.IQueryable`1'. Only
primitive types, enumeration types and entity types are supported. "
Here is the query I'm applying in my index action:
var viewModel = new PointsViewModel();
viewModel.Point = db.Point.ToList();
viewModel.Redeem = db.Redeem.ToList();
TempData["UserPoints"] = null;
var usrname = (from a in db.Instructors
where a.Email == User.Identity.Name
select new { a.PersonID });
if (usrname.Count().Equals(0))
{
TempData["UserPoints"] = "You have not earn any points yet.";
return View();
}
viewModel.instructor = db.Instructors
.Where(i => i.PersonID.Equals(usrname))// if I directly insert id here then it works properly but I don't want direct inserts
.Single();
PopulateAssignedPointData(viewModel.instructor);
return View(viewModel);
Please help me with this please...I am unable to find any solution on google
It's because you're passing usrname as a parameter to another query. usrname is a query, not a value, so you need to retrieve a value from the query (in this case, by using First(), but you could just as easily use Single() if you like) before you can use it as a parameter in another query. I would recommend the following changes:
if (!usrname.Any())
{
TempData["UserPoints"] = "You have not earn any points yet.";
return View();
}
var personId = usrname.First();
viewModel.instructor = db.Instructors
.Where(i => i.PersonID.Equals(personId))
.Single();
I also changed usrname.Count().Equals(0) to !usrname.Any() as it is more idiomatic (it will use the exists keyword in SQL, rather than count)
Try to use this:
viewModel.instructor = db.Instructors
.Where(i => usrname.Any(u => u.PersonID == i.PersonID))
.Single();

Can't able to access data by LINQ query

[HttpPost]
public ActionResult Playlist(String ID)
{
long playid=Convert.ToInt64(ID);
var q = from client in Clients
join m in db.Playlists on client.ClientId equals m.ClientId
join meta in db.ContentMetaDatas on m.PlaylistId equals meta.PlaylistId
where m.PlaylistId.Equals(playid)
orderby m.PlaylistId descending
select new SimpleViewModel
{
ID = m.PlaylistId,
Live = false,
Expired = meta.ContentMetaDataExpiryDateTime != null,
Details = m.PlaylistShortDescription,
ImageUrl = meta.ContentMetaDataImage,
Title = m.PlaylistTitle
};
return Json(q.ToPage(p, "ID desc"), JsonRequestBehavior.DenyGet);
}
As shown in the above code of controller I want to fetch data those are returned in JSON data format & used in view.
But As I have to convert the string into long datatype,
what can I do for getting data. Is there anything wrong in the above code??

Resources