List in asp.net linq query not working - asp.net

const string keyword = "manoj";
rsp.DataSource = company.GetCompanySearch(keyword);
rsp.DataBind();
public List<Company> GetCompanySearch(string keyword)
{
using (var context = huntableEntities.GetEntitiesWithNoLock())
{
List<Company> query = context.Companies.ToList();
if (!string.IsNullOrEmpty(keyword))
{
keyword = keyword.ToLower();
query = (List<Company>) query.Where(u=>u.CompanyName.Contains(keyword)
|| u.EmailAdress.Contains(keyword)
||u.MasterCountry.Description.Contains(keyword)
||u.MasterIndustry.Description.Contains(keyword)
||u.CompanyDescription.Contains(keyword)
||u.CompanyHeading.Contains(keyword));
}
return query.ToList();
}
}
The following code throwing the following exception:
{"Unable to cast object of type 'WhereListIterator1[Data.Company]' to type 'System.Collections.Generic.List1[Data.Company]'."}

"(List) query.Where()" is equal to "(List) (query.Where())", so this will throw that exception.
Should use query.Where().ToList() but not a explicit cast.
Further, better not put "List query = context.Companies.ToList();" before your "if" statement. In this case, no matter keyword is empty or not, it will query all records into memory and it will cause performance problem.
Can change to below
IQueryable<Company> query = context.Companies; //Remove ToList()
if (!string.IsNullOrEmpty(keyword))
{
keyword = keyword.ToLower();
// Remove cast
query = query.Where(u=>u.CompanyName.Contains(keyword)
|| u.EmailAdress.Contains(keyword)
||u.MasterCountry.Description.Contains(keyword)
||u.MasterIndustry.Description.Contains(keyword)
||u.CompanyDescription.Contains(keyword)
||u.CompanyHeading.Contains(keyword));
}
return query.ToList();

Related

Project to a Known Type using Simple.OData.Client Dynamic Syntax

Simple.OData.Client has a typed and dynamic (and basic) syntax.
I like the typed, but I don't want to build out all my types. In the end I really only need two or so types in the results I get.
But my queries need more types to properly filter the results.
So I want to use the dynamic syntax. But I want to cast the results to classes I have.
I can easily do this manually, but I thought I would see if Simple.OData.Client supports this before I go writing up all that conversion code for each query.
Here is some dynamic syntax code that runs without errors:
client.For(x.Client).Top(10).Select(x.ClientId, x.Name).FindEntriesAsync();
Here is an example of what I had hoped would work (selecting into a new Client object)
client.For(x.Client).Top(10).Select(new Client(x.ClientId, x.Name)).FindEntriesAsync();
But that kind of projection is not supported (I get an "has some invalid arguments" error).
Is there a way to support projection into an existing class when using the dynamic syntax of Simple.OData.Client?
EDIT: The code below works. But it's performance is terrible. I decided to abandon it and write hand written mappers for each type I needed.
This is what I came up with:
dynamic results = oDataClient.For(x.Client).Select(x.ClientId, x.Name).FindEntriesAsync().Result;
var listOfClients = SimpleODataToList<Client>(results);
public List<T> SimpleODataToList<T>(dynamic sourceObjects) where T : new()
{
List<T> targetList = new List<T>();
foreach (var sourceObject in sourceObjects)
{
// This is a dictionary with keys (properties) and values. But no
// matter what sourceObject is passed in, the values will always be
// the values of the first entry in the sourceObjects list.
var sourceProperties = ((System.Collections.Generic.IDictionary<string, object>)sourceObject);
var targetProperties = typeof(Client).GetProperties().Where(prop => prop.CanWrite);
var targetObject = new T();
foreach (var targetProperty in targetProperties)
{
if (sourceProperties.ContainsKey(targetProperty.Name))
{
var sourceValue = GetProperty(sourceObject, targetProperty.Name);
targetProperty.SetValue(targetObject, sourceValue, null);
}
}
targetList.Add(targetObject);
}
return targetList;
}
public static object GetProperty(object o, string member)
{
if (o == null) throw new ArgumentNullException("o");
if (member == null) throw new ArgumentNullException("member");
Type scope = o.GetType();
IDynamicMetaObjectProvider provider = o as IDynamicMetaObjectProvider;
if (provider != null)
{
ParameterExpression param = Expression.Parameter(typeof(object));
DynamicMetaObject mobj = provider.GetMetaObject(param);
GetMemberBinder binder = (GetMemberBinder)Microsoft.CSharp.RuntimeBinder.Binder.GetMember(0, member, scope, new CSharpArgumentInfo[] { CSharpArgumentInfo.Create(0, null) });
DynamicMetaObject ret = mobj.BindGetMember(binder);
BlockExpression final = Expression.Block(
Expression.Label(CallSiteBinder.UpdateLabel),
ret.Expression
);
LambdaExpression lambda = Expression.Lambda(final, param);
Delegate del = lambda.Compile();
return del.DynamicInvoke(o);
}
else
{
return o.GetType().GetProperty(member, BindingFlags.Public | BindingFlags.Instance).GetValue(o, null);
}
}
It was made much harder because normal casts and such for the dynamic objects returned would only give the first object in the list over and over. The GetProperty method works around this limitation.

Running a SELECT on a specific column that matches an input from kotlin function, throws null pointer

I am trying to write a method that takes a username as its input and creates a SQL query statement which is then executed. As of right now, I am getting a NullPointer when I try to call result.getObject().
Here is my method for creating the SQL statement dynamically:
fun getByUsername(name: String): User?{
val sql = """SELECT * FROM usertable WHERE username="$name";"""
val result = DatabaseController().trySql(sql)
if (result != null) {
if (!result.isBeforeFirst) {
println("User was not found...")
return null
} else {
println("User found....")
return User(result.getObject("username").toString(),
result.getObject("password").toString(),
result.getObject("admin").toString().toBoolean())
}
}
return null
}
Method that executes query:
fun trySql(sqlCommand: String): ResultSet? {
var conn = this.connect()
println("trySql()-------Running query $sqlCommand")
var result = conn?.createStatement()?.executeQuery(sqlCommand)
conn?.close()
return result
}
The username I am running it on is in my table too, so that is not the issue. My method that creates a row in my table is working properly, so I know there is no issue with connecting to the database.
EDIT
If I just return result in trySql(), I no longer get any errors, but from my reading I am supposed to close connections after use?
Why you are having issues
You are closing the connection, which makes the ResultSet you get back no longer useful. You will have access to the result object, but the result object will be unable to read data from SQLite, leading to errors.
How to fix
You can pass some code to your trySql function, which will be performed with the connection still open, and then close after the passed block.
Example
Library
class Con(val con: Connection = DriverManager.getConnection(URL)): AutoCloseable by con {
fun <T> withSQL(query: String, block: (ResultSet)->T): T {
con.createStatement().use { statement ->
statement.executeQuery(query).use { results ->
return block(results)
}
}
}
}
Usage
Con().use { con ->
val result: Int = con.withSQL("SELECT * from example WHERE name='test'") {
it.getInt(1)
}
}

How to pass non-optional NULL parameters to a Stored Proc using OrmLite

I'm using OrmLite against an existing SQL Server database that has published stored procedures for access. One of these SPs takes 3 int parameters, but expects that one or another will be null. However, none of the parameters are declared optional.
Here's the code I've tried:
using (IDbConnection scon = myFactory.OpenDbConnection())
{
rowCount = scon.SqlScalar<int>("EXEC myProc #FileID, #FileTypeID, #POID",
new
{
FileID = req.FileId,
FileTypeID = (int?)null,
POID = req.PoId,
});
}
But this produces a SqlException: Must declare the scalar variable "#FileTypeID". Examining the SQLParameterCollection under the covers shows that only two parameters are being generated by OrmLite.
Is it possible to call this SP with a null parameter?
It's not supported with SqlScalar. When you look at the code then you can see that SqlScalar methods from class ServiceStack.OrmLite.OrmLiteReadExtensions execute SetParameters method responsible for adding parameters to query with second parameter(excludeNulls) equal true I don't know why- mythz should answer for this ;).
If you want to fix it then you have change all SqlScalar methods to invoke SetParameters with true and SetParameters method should look like following(must support DBNull.Value not null)
private static void SetParameters(this IDbCommand dbCmd, object anonType, bool excludeNulls)
{
dbCmd.Parameters.Clear();
lastQueryType = null;
if (anonType == null) return;
var pis = anonType.GetType().GetSerializableProperties();
foreach (var pi in pis)
{
var mi = pi.GetGetMethod();
if (mi == null) continue;
var value = mi.Invoke(anonType, new object[0]);
if (excludeNulls && value == null) continue;
var p = dbCmd.CreateParameter();
p.ParameterName = pi.Name;
p.DbType = OrmLiteConfig.DialectProvider.GetColumnDbType(pi.PropertyType);
p.Direction = ParameterDirection.Input;
p.Value = value ?? DBNull.Value; // I HAVE CHANGED THAT LINE ONLY
dbCmd.Parameters.Add(p);
}
}
When you change code then you can set null for parameters in the following way:
var result = db.SqlScalar<int>("EXEC DummyScalar #Times", new { Times = (int?)null });
In my opinion you can describe it as a defect on github and I can make pull request.

Picking out Just JSON Data Returned from ASP.NET MVC3 controller Update

I've got data returned from my JavaScript client that just includes the data that has changed. That is, I may have an array with each row containing 10 columns of JSON downloaded, but on the Update, only the data that is returned to me is the data that got updated. On my update, I only want to update those columns that are changed (not all of them).
In other words, I have code like below but because I'm passing in an instance of the "President" class, I have no way of knowing what actually came in on the original JSON.
How can I just update what comes into my MVC3 update method and not all columns. That is, 8 of the columns may not come in and will be null in the "data" parameter passed in. I don't want to wipe out all my data because of that.
[HttpPost]
public JsonResult Update(President data)
{
bool success = false;
string message = "no record found";
if (data != null && data.Id > 0)
{
using (var db = new USPresidentsDb())
{
var rec = db.Presidents.FirstOrDefault(a => a.Id == data.Id);
rec.FirstName = data.FirstName;
db.SaveChanges();
success = true;
message = "Update method called successfully";
}
}
return Json(new
{
data,
success,
message
});
}
rec.FirstName = data.FirstName ?? rec.FirstName;
I would use reflection in this case because the code will be too messy like
if (data.FirstName != null)
rec.FirstName = data.FirstName
.
.
.
and so on for all the fields
Using reflection, it would be easier to do this. See this method
public static void CopyOnlyModifiedData<T>(T source, ref T destination)
{
foreach (var propertyInfo in source.GetType().GetProperties())
{
object value = propertyInfo.GetValue(source, null);
if (value!= null && !value.GetType().IsValueType)
{
destination.GetType().GetProperty(propertyInfo.Name, value.GetType()).SetValue(destination, value, null);
}
}
}
USAGE
CopyOnlyModifiedData<President>(data, ref rec);
Please mind that, this won't work for value type properties.

Code practice to handle empty result set in Linq to custom list

My Question is how do I handle a null set returned from a linq query if I am loading it into a custom class.
example
queryResults = queryResults.Select(p => new specialItems(p.ID, p.SECTION, p.PROGRAM, p.EVENT).ToList<specialItems>();
...
public class specialItems
{
public string Id { get; set; }
public string Section { get; set; }
public string Program { get; set; }
public string Event { get; set; }
public courseItems(string id, string section, string program, string event)
{
this.Id = id;
this.Section = section;
this.Program = program;
this.Event = event;
}
}
Currently this query works great until the result set is empty, then I get:
"Object reference not set to an instance of an object."
I need the query to return an empty List if the result set is empty.
UPDATE - Asided from the invalid redeclaration of a variable (fixed) I did find that the issue was higher up in the initial construction of the linq query. This became apparent when I received several good suggestions and removed the error. Once I fixed the original query things worked swimmingly.
Use the null coalescing operator (??).
List<specialItems> queryResults = queryResults.Select(p => new specialItems(p.ID, p.SECTION, p.PROGRAM, p.EVENT).ToList<specialItems>() ?? new List<specialItems>();
EDIT: Yeah, looking at what you have there a little closer, it's the ToList that's blowing up when this happens. You might have to split it up a bit.
var temp = queryResults.Select(p => new specialItems(p.ID, p.SECTION, p.PROGRAM, p.EVENT);
List<specialItems> results = temp == null ? new List<specialItems>() : temp.ToList<SpecialItems>();
Have to do it this way, because there's no good spot to put the null coalescing operator in this case.
Robaticus is mostly right, use the null coalescing operator (??). Howerver, since you didn't include the stack trace, I assume your code is throwing because queryResults is initially null. By the time you get to the ?? operator, you've already thrown the exception, because you tried to dereference queryResults.
Also, the code you have doesn't make a ton of sense, because queryResults is already defined within that scope by the time you get to that line. You can't redefine a variable that has already been declared locally in that scope.
List<SpecialItems> queryResults = GetSomeResults();
queryResults = (queryResults ?? new List<SpecialItems>())
.Select(p => new SpecialItems(p.ID, p.SECTION, p.PROGRAM, p.EVENT))
.ToList<SpecialItems>();
If you can get the function or line that spits out the original version of queryResults to return an empty list instead of null, then try to do that, or coalesce the results on that line. That's probably better than having all that code on the query line :)
List<SpecialItems> queryResults = GetSomeResults() ?? new List<SpecialItems>();
queryResults = queryResults
.Select(p => new SpecialItems(p.ID, p.SECTION, p.PROGRAM, p.EVENT))
.ToList<SpecialItems>();
Linq returns an empty list if there are no results, never null. Therefore, the problem is certainly not that queryResults.Select() returns null.
What is probably going on is that we're looking at a lazily evaluated linq-to-objects 'query'. ToList() triggers the evaluation of it, and probably the nullreference exception occurs in a lambda expression higher up the chain.
Neither Enumerable.Select, nor Queryable.Select, nor Enumerable.ToList return null.
The query is not realized until ToList enumerates it. During that enumeration, a null reference exception is occuring due to code you have not posted in the question.
Consider this code with and without the commented line:
List<int> source = Enumerable.Range(1, 10).ToList();
IEnumerable<int> query = null;
try
{
query = source.Where(i => 1 / i > 0);
}
catch(Exception ex)
{
Console.WriteLine("Exception was caught {0}", ex.Message);
}
// source.Add(0);
List<int> result = query.ToList();
Consider this code with and without the commented line:
DataContext myDC = new DataContext();
string name = null;
IQueryable<Person> query = myDC.Persons.Where(p => p.Name.StartsWith(name));
// name = "Zz";
List<Person> result = query.ToList();

Resources