DataTable Linq with two join statements in C# - c#

My code:
var Result = from TempRow in ArrAbsDiff
where TempRow.Strike == StrikeOfMinAbsDiff
select TempRow.PutMidPrice;
I know that the above code return just one value of type decimal (maybe double). However, Result is of type Enumerable and I could not easily write Result + 2. I need to convert it property. I can do it through the following code:
var Result = (from TempRow in ArrAbsDiff
where TempRow.Strike == StrikeOfMinAbsDiff
select TempRow.PutMidPrice).Min();
Is there more efficient way to accomplish it?
Regards,

I know that the above code return just one value of type decimal
Then use First method instaed of Min.

At compile time, it's unknown whether the query you have returns 1 record or more than 1 record. So, it assumes a list of them.
I don't know if there is a performance difference between them, I typically use .Single() to get the single record. It's more clear that I want a single record and not, for example, the minimum one.

Try using FirstOrDefault()" this selects the first result returned (as you know only one value will be returned). if a value is not returned the Result will be null, catch this in an if statement like below:
var Result = (from TempRow in ArrAbsDiff
where TempRow.Strike == StrikeOfMinAbsDiff
select TempRow.PutMidPrice).FirstOrDefault();
if (Result == null)
return; // or error message
this will also keep the type of value returned
(typed this of the top of my head, may need slight changes!)

Related

C# Linq return object

I'm trying to implement a method:
public Referee GetRefereeById(int refereeId)
{
var result = from b in Referees
where b.PersonId.Equals(refereeId)
select b;
return (Referee)result;
}
This method is supposed to return a referee object. Any idea what I'm doing wrong?
Try
return result.FirstOrDefault();
Your select can return more than 1 referee.
Try
public Referee GetRefereeById(int refereeId)
{
var result = (from b in Referees
where b.PersonId.Equals(refereeId)
select b).FirstOrDefault();
return (Referee)result;
}
You could use .Single(), but FirstOrDefault is a safer option. I am assuming PersonId should be unique, so that shouldn't matter, but if no matching data is found, Single will throw an exception.
You need to return a single referee, not many of them.
Use FirstOrDefault - Returns the first element of a sequence, or a default value if the sequence contains no elements. (MSDN: http://msdn.microsoft.com/en-us/library/bb340482%28v=vs.110%29.aspx)
public Referee GetRefereeById(int refereeId)
{
return Referees.FirstOrDefault(r => r.PersonId.Equals(refereeId));
}
This will return null if one isn't found.
In case you expect to find a result you should do
Return result.Single();
If not sure it exists do and check for null:
Return result.SingleOrDefault();
I would implement the Single() methods instead of the First().
Your method return a single referee to the caller. You want to make sure you actually get one unique referee in every case. When there is more then 1 matching your criteria you are introducing some very subtile bugs in your application. Assuming you are working against the correct record but instead you could be retrieving a complete different one.
Better use the First() methods if you have a list that you order on some sort of record and really intend to get the first row based on the ordering.
try this:
public Referee GetRefereeById(int refereeId)
{
var result = from b in Referees
where b.PersonId == refereeId
select b;
return result.FirstOrDefault();
}
there is also no need to do the cast for returning the result.
when you say it is supposed to return the object, what does it do?
var result = (from b in Referees
where b.PersonId.Equals(refereeId)
select b).SingleOrDefault();
return result;
This returns a Referee object.
Your query (more specifically the Where function) can return zero results. Use Single, SingleOrDefault, First or FirstOrDefault depending on your needs.
e.g. return (Referee)result.SingleOrDefault();

System.InvalidCastException: Specified cast is not valid. Error

I am on a C# ASP.NET project.
I have a MySQL table with a userid field of type int.
Now I want to get the number of rows where value of userid equals certain value using LINQ.
To achieve this, I wrote the following method:
public int getCount(int usercode) {
int count = 0;
DataTable mytable = getAllRowsAndReturnAsDataTable(); // assigning a DataTable value to mytable.
if (mytable.Rows.Count > 0) {
count = (from x in mytable.AsEnumerable() where x.Field<Int32>("userid") == usercode select x).Count();
}
return count;
}
but it is showing error System.InvalidCastException: Specified cast is not valid. showing count = (from x in mytable.AsEnumerable() where x.Field<Int32>("userid") == usercode select x).Count(); in red highlight area.
I don't know what I did wrong here. Please help.
The most likely cause of the InvalidCastException is the x.Field<Int32>("userid") line. The Field<T> extension method will throw an InvalidCastException in the case where the actual type of the data doesn't match the type which was passed to Field<T>. Hence if userid wasn't an Int32 this would throw.
EDIT
Based on your comments the type of userid is actually UInt32 and not Int32. This is what is causing the problem. Try using the following and it should work
x.Field<UInt32>("userid")
Without looking at the data coming back from your database I can only guess that the following part of your LINQ is at fault:
x.Field<Int32>("userid")
Your userid column value probably isn't an int, I would put my money on it being NULL?
UPDATE: Can you confirm it's not the Field call that is breaking? Simply change your code to something like this without the Field call:
public int getCount(int usercode){
int count = 0;
DataTable mytable = getAllRowsAndReturnAsDataTable(); // assigning a DataTable value to mytable.
if (mytable.Rows.Count > 0) {
count = mytable.AsEnumerable().Count(); // No WHERE function call so no casting.
}
return count;
}
You could also inspect what the values are that are returned by mytable.AsEnumerable() in a watch window for example to ensure that everything looks correct. If the code above works then it's the Field call blowing up. Find out which row cannot be cast to an Int32 and go from there.
If it is in fact NULL, there are a number of ways you can solve this.
Make sure you don't return NULL from your database query, in MySQL you can use IFNULL.
Use a nullable type for the generic being passed into Field:
where x.Field("userid") == (Int32?)usercode

Using C # LINQ to Select within 2 tags that has a descendant node equal to a certain value?

I'm trying to select all objects within 2 tags specifically <AR>'s that contains an element that's a descendant of <AR>: <RL> with a certain value say 2. <RL> can be buried an arbitrary number of levels within <AR>'s, but will always be within <AR>. How can I do this in LINQ?
EX1:
<ARS>
<AR>
<EI> </EI>
<RL>5</RL>
</AR>
<AR>
<EI> </EI>
<RL>2</RL>
</AR>
</ARS>
Result :
<AR>
<EI> </EI>
<RL>2</RL>
</AR>
I tried using
IEnumerable<XNode> test_var = from result in doc.Descendants("AR")
where result.DescendantNodes()
But go from here, but this threw an error msg
var test_var = from result in doc.Descendants("AR")
where result.Descendants("RL").Any(x => (int)x == 2)
select result;
First problem is you need a select statement, such as adding select result.
Additionally your where needs to be a boolean. It sounds like you are looking for existence, which is frequently handled via the Any() extension method.
var searchString = "2";
IEnumerable<XElement> test_var = from result in doc.Descendants("AR")
where result.Descendants("RL").Any(xelm => xelm.Value == searchString)
select result;

Dapper Multiple Results From single query

Hi i am trying to get to grips with Dapper.
My situation is i want to pull two values from a query into two separate strings. Im not sure if i am going about this in the correct way, but this is what i am doing:
string sql = #"Select type, name
FROM ZipData
WHERE Zip = #zip";
using (var multi = conn.QueryMultiple(sql, new { zip = zip }))
{
string result = multi.Read<string>().SingleOrDefault();
}
And i am getting Cannot access a disposed object. Object name: 'GridReader'. when trying to read the second string.The thing is it gets the first value correctly and has both the fields in in the reader i am trying to get. Im sure im misusing the api.
What am i doing wrong here? Ive googled but can find a specific example.
You are mis-using QueryMultiple. That is defined for compound SQL statements that return multiple result sets. Something like:
SELECT Foo FROM MyTable;
SELECT Bar FROM MyOtherTable;
On the other hand, you are trying to get two different columns from a single result set, so you should just use the normal Query method:
var result = conn.Query(sql, new { zip = zip }).Single();
var type = result.type;
var name = result.name;
Query returns an enumerable (because generally a query can return multiple rows). It appears that you only want one row, however, so we invoke .Single at the end to just get that row. From there, the return type is dynamic so you can simply refer to the properies implied by the columns in your SELECT statement: type and name.

LINQ to returns count even the list is empty

I have this block of code inside another LINQ statement.
VideoLinks = (from video in m.VideoLinks.DefaultIfEmpty(new VideoGallery())
orderby video.CreatedDate
select new VideoGallery()
{
Source = video.Source,
Type = video.Type,
Links = video.Links,
Title = video.Title
}).ToList()
unfortunately if dont use DefaultIfEmpty its through me an exception. If I use DefaultIfEmpty i give count as 1 for videolinks even if m.VideoLinks is null.
So now how can avoid getting count 1 if m.VideoLinks is null
DefaultIfEmpty is going to give you a default value. It counts as an item when you call ToList() on it...thus your count is 1.
This looks like you are using linq-to-objects, so you should add a where video != null
VideoLinks = (from video in m.VideoLinks
where video != null
orderby video.CreatedDate
select new VideoGallery()
{
Source = video.Source,
Type = video.Type,
Links = video.Links,
Title = video.Title
}).ToList()
wllmsaccnt is correct - your problem is the "DefaultIfEmpty" portion of your statement. By definition, you are requesting that there be at least one item in the collection, according to the definition of this method:
Returns the elements of the specified sequence or the specified value
in a singleton collection if the sequence is empty
I think the important question here is what exception are you receiving when you don't use DefaultIfEmpty? If you tell us that, perhaps we can help you avoid it...

Categories

Resources