Is there a way to get the code below to return null if no objects are found?
var news = (from c in childs
where c.Name.ToLower().Contains("folder")
select c).First();
You want to use FirstOrDefault() instead of First(). It will do exactly what you want.
You should call FirstOrDefault<T>, which will return default(T) if there are no elements.
default(T) will be null for reference and nullable types, 0 for numeric types (byte, int, double, etc), and new T() for structures (which cannot be null)
Related
I have the following model method:
public IQueryable<CustomerVLAN> CustomerVLANS(int customerid)
{
string customername = entities.AccountDefinitions.SingleOrDefault(a=>a.ORG_ID == customerid).ORG_NAME;// .tolist since i will be querying different context
return tms.CustomerVLANS.Where(String.Compare(a=>a.CustomerName.ToString(), customername.ToString(), StringComparison.OrdinalIgnoreCase));
}
but I am unable to use the String.Compare inside my where clause ,,,
Provided CustomerName and customername are strings, you can try
return tms.CustomerVLANS.Where(a=>a.CustomerName.ToUpper() == customername.ToUpper());
The Where extension filters an IEnumerable using a supplied predicate function: Func<TSource, bool>, in your case Func<CustomerVLAN, bool>.
Your line "String.Compare(a=>a.CustomerName.ToString(), customername.ToString(), StringComparison.OrdinalIgnoreCase)" returns an integer, rather than a Func<CustomerVLAN, bool> delegate (I'm also not sure if there's an overload of string Compare which expects the values you've provided).
If you wanted to use that particular function, you'd have to do something like this (using a Lambda expression):
CustomerVLANS.Where(x => (String.Compare(x.CustomerName, customername, StringComparison.OrdinalIgnoreCase) == 0));
Unless there's a particular reason for it, you may well be better of using String.Equals, which returns a boolean:
CustomerVLANS.Where(x => (String.Equals(x.CustomerName, customername)));
You may need your ToString(), depending on what type CustomerName is.
I have a problem with the following method:
public IQueryable<Customer> ListCustomers(int? parentId)
{
Debug.Assert(parentId == null);
//var list = _customerRepository.List().Where(c => c.ParentId == null);
var list = _customerRepository.List().Where(c => c.ParentId == parentId);
return list;
}
I have one Customer in my DB with a ParentId of null. When I call the method with ListCustomers(null), list is empty for the return statement. If I swap the commented out line in and query with a hard-coded null, then list contains my one customer.
What could cause this difference between these two queries? Why is the one with c.ParentId == parentId not returning anything?
Becouse the Nullable type the linq provider will not generate the proper IS NULL check. See this answer for further information: https://stackoverflow.com/a/785501/1195510
EF translates your query with int? to something like this:
DECLARE #parentId Int = null
SELECT ... WHERE ParentId = #parentId
When this is executed on the database, it doesn't do what you expect because in SQL [column] = NULL is always false.
I agree EF could handle this better, but as a workaround, you can write something like this:
.Where( c => !parentId.HasValue
? !c.ParentId.HasValue
: c.ParentId.Value == parentId.Value
)
EF will then generate a ( somewhat verbose ) SQL statement with the correct IS NULL predicates.
with nullable types you have to use it like this:
.Where(c=> object.Equals(c.ParentId, parentId))
I have List where MyType : DynamicObject. The reason for MyType inheriting from DynamicObject, is that I need a type that can contain unknown number of properties.
It all works fine until I need to filter List. Is there a way I can do a linq that will do something like this:
return all items where any of the properties is empty string or white space?
(from the comment) can I do above linq query with List?
Yes, here is how you can do it with ExpandoObject:
var list = new List<ExpandoObject>();
dynamic e1 = new ExpandoObject();
e1.a = null;
e1.b = "";
dynamic e2 = new ExpandoObject();
e2.x = "xxx";
e2.y = 123;
list.Add(e1);
list.Add(e2);
var res = list.Where(
item => item.Any(p => p.Value == null || (p.Value is string && string.IsNullOrEmpty((string)p.Value)))
);
The ExpandoObject presents an interface that lets you enumerate its property-value pairs as if they were in a dictionary, making the process of checking them a lot simpler.
Well as long as each object's properties are not unknown internally to themselves you could do it.
There isn't a great generic way to test all the properties of a dynamic object, if you don't have control over the DynamicObject you hope the implementer implemented GetDynamicMemberNames() and you can use the nuget package ImpromptuInterface's methods for getting the property names and dynamically invoking those names.
return allItems.Where(x=> Impromptu.GetMemberNames(x, dynamicOnly:true)
.Any(y=>String.IsNullOrWhiteSpace(Impromptu.InvokeGet(x,y));
Otherwise, since it's your own type MyType you can add your own method that can see internal accounting for those member values.
return allItems.Where(x => x.MyValues.Any(y=>String.IsNullOrWhitespace(x));
When using sum with lambda in Linq to SQL using the following code:
int query = (from f in odc.RDetails
where f.ticketID == int.Parse(ticket.ToString())
select f).Sum(x => x.Rate);
I get the following error:
The null value cannot be assigned to a member with type System.Int32 which is a non-nullable value type.
. You have to make sure x.Rate is an int, and not an int? (an int that accepts null as a value).
. If the query has no elements, .Sum won't do anything and will return null. Choose a default value, let's say 0.
var query = from f in odc.RDetails
where f.ticketID == int.Parse(ticket.ToString())
select f;
int result = query.Any()
? query.Sum(x => x.Rate ?? 0) // use the ?? if x.Rate is an "int?".
: 0; // default value you can choose.
I would break the int.Parse(ticket.ToString()) onto its own line to isolate that parse from the Linq for debugging.
We don't know whether that is throwing the exception or if one of the RDetails.Rate values is null. Is it indeed a Nullable<int>?
If RDetails.Rate is a Nullable<int>, then you could ...Sum(x => x.Rate ?? 0) and avoid the exception.
My result returns null.
IEnumerable<DataRow> result = ( from r in db.vedhaeftedeFilers.AsEnumerable() where r.beskedId == id select new { r.filnavn, r.filtype, r.data })as IEnumerable<DataRow>;
there are data in the database, and the id are correct. I am guessing that it has
something to do with my use of IEnumerable, but cant figure out what the problem is.
The as operator will return null if the object you are passing is not actually an IEnumerable<DataRow>, which it obviously is not because you are projecting into an anonymous type with select new { ... }.
As an aside, the AsEnumerable() call will ruin your performance by making your database table behave like a dumb array.
What exactly are you trying to do here?
select new { r.filnavn, r.filtype, r.data }
That creates an anonymous type with read only properties filnavn, filtype and data. Thus the type of the LINQ comprehension expression (from ... select) is IEnumerable<anonymous>.
This type does not implement IEnumerable<DataRow>, so as Jon notes, it will return null.
When you do this:
select new { r.filnavn, r.filtype, r.data }
...you are returning a collection of an anonymous type. This is a problem because you're trying to cast this collection to IEnumerable<DataRow>. Since you're using as to cast, it's "dying silently" and returning null since casting with the as keyword doesn't throw an InvalidCastException if the cast fails (as opposed to casting with parethesis like MyClass x = (MyClass)MyObj).
Try this instead:
var result = ( from r in db.vedhaeftedeFilers.AsEnumerable() where r.beskedId == id select new { r.filnavn, r.filtype, r.data });
Notice I used var and didn't attempt to cast the result to a type.