linq distinct query? - linq

I need a little help with Linq i have a DB table with restourants tables in it. In the DB i have "TableNumber, Floor , RestaurantID" I would like to get list of all floors. For example if i have this list:
TableNumber, Floor , RestaurantID
10 1 1
11 1 1
12 2 1
13 2 1
14 3 1
I would like to get only "1,2,3".
Right now the method returns all rows.
public IEnumerable<ListPad.Item> GetFloorsListPads(SSF.ART.Key restaurant_id)
{
return from restaurant_floor in EnterpriseTouchRestaurantApplication.TouchRestaurant.AllRestaurantTables
where restaurant_floor.RestaurantID == restaurant_id && restaurant_floor.Active == true
orderby restaurant_floor.Floor
select new ListPad.Item()
{
Color = Color.SkyBlue,
Text = string.Format("{0}", restaurant_floor.Floor),
Tag = restaurant_floor
};
}
Thanks for all the help in advance.

You need either one or two things, depending of whether or not ListPad.Item defines equality (by overriding Equals and GetHashCode) in the way you describe. If so, then adding .Distinct() to your query will give you the distinct items. If not, you can do it one of three ways.
Return an anonymous type, call Distinct on it, and map to the actual type (lazy way)
Implement IEquatable on ListPad.Item, overriding Equals and GetHashCode (you'll need to research how to properly implement GetHashCode so it matches your equality conditions)
Define an IEqualityComparer<ListPad.Item> that defines your equality.
1 is the lazy way but is less coding. 2 is handy if your conditions define equality for ALL uses of ListPad.Item (not just this particular scenario). 3 separates the equality check from the actual type, which is handy if you have other cases where equality would be defined differently.

Related

Strange behaviour when using FILTER to filter a different table with no direct relationship?

I have two facts tables, First and Second, and two dimension tables, dimTime and dimColour.
Fact table First looks like this:
and facet table Second looks like this:
Both dim-tables have 1:* relationships to both fact tables and the filtering is one-directional (from dim to fact), like this:
dimColour[Color] 1 -> * First[Colour]
dimColour[Color] 1 -> * Second[Colour]
dimTime[Time] 1 -> * First[Time]
dimTime[Time] 1 -> * Second[Time_]
Adding the following measure, I would expect the FILTER-functuion not to have any affect on the calculation, since Second does not filter First, right?
Test_Alone =
CALCULATE (
SUM ( First[Amount] );
First[Alone] = "Y";
FILTER(
'Second';
'Second'[Colour]="Red"
)
)
So this should evaluate to 7, since only two rows in First have [Alone] = "Y" with values 1 and 6 and that there is no direct relationship between First and Second. However, this evaluates to 6. If I remove the FILTER-function argument in the calculate, it evaluates to 7.
There are thre additional measures in the pbix-file attached which show the same type of behaviour.
How is filtering one fact table which has no direct relationship to a second fact table affecting the calculation done on the second table?
Ziped Power BI-file: PowerBIFileDownload
Evaluating the table reference 'Second' produces a table that includes the columns in both the Second table, as well as those in all the (transitive) parents of the Second table.
In this case, this is a table with all of the columns in dimColour, dimTime, Second.
You can't see this if you just run:
evaluate 'Second'
as when 'evaluate' returns the results to the user, these "Parent Table" (or "Related") columns are not included.
Even so, these columns are certainly present.
When a table is converted to a row context, these related columns become available via RELATED.
See the following queries:
evaluate FILTER('Second', ISBLANK(RELATED(dimColour[Color])))
evaluate 'Second' order by RELATED(dimTime[Hour])
Similarly, when arguments to CALCULATE are used to update the filter context, these hidden "Related" columns are not ignored; hence, they can end up filtering First, in your example. You can see this, by using a function that strips the related columns, such as INTERSECT:
Test_ActuallyAlone = CALCULATE (
SUM ( First[Amount] ),
First[Alone] = "Y",
//This filter now does nothing, as none of the columns in Second
//have an impact on 'SUM ( First[Amount] )'; and the related columns
//are removed by the INTERSECT.
FILTER(
INTERSECT('Second', 'Second')
'Second'[Colour]="Red"
)
)
(See these resources that describe the "Expanded Table"
(this is an alternative but equivalent explanation of this behaviour)
https://www.sqlbi.com/articles/expanded-tables-in-dax/
https://www.sqlbi.com/articles/context-transition-and-expanded-tables/
)

Getting minimum of attribute of hashes/objects in arrays

I created following syntax for two methods and cant put them together. Further I hope there's a shorter way to write this because it's not really lean:
#e = #c_entries.find_all{|i| i.order_no.between?(1,5)}
Gives me an array of all objects that's order_no is between 1 and 5!!
#f = #c_entries.all(:select => :order_no).collect(&:order_no).min
Creates an array of all order_no and gives me the minimum!
What I am trying now is to get the minimum order_no within all objects which order_no is between 1 and 5 as short as possible.
Any ideas?
If #c_entries contains a collection of particular model in your application, you can take advantage of ActiveRecord's query interface:
#c_entries.where(order_no: 1..5).select(:order_no).min
There are various other ways to narrow down your queries: http://guides.rubyonrails.org/active_record_querying.html#conditions

Linq query returns duplicate results when .Distinct() isn't used - why?

When I use the following Linq query in LinqPad I get 25 results returned:
var result = (from l in LandlordPreferences
where l.Name == "Wants Student" && l.IsSelected == true
join t in Tenants on l.IsSelected equals t.IsStudent
select new { Tenant = t});
result.Dump();
When I add .Distinct() to the end I only get 5 results returned, so, I'm guessing I'm getting 5 instances of each result when the above is used.
I'm new to Linq, so I'm wondering if this is because of a poorly built query? Or is this the way Linq always behaves? Surely not - if I returned 500 rows with .Distinct(), does that mean without it there's 2,500 returned? Would this compromise performance?
It's a poorly built query.
You are joining LandlordPreferences with Tenants on a boolean value instead of a foreign key.
So, most likely, you have 5 selected land lords and 5 tenants that are students. Each student will be returned for each land lord: 5 x 5 = 25. This is a cartesian product and has nothing to do with LINQ. A similar query in SQL would behave the same.
If you would add the land lord to your result (select new { Tenant = t, Landlord = l }), you would see that no two results are actually the same.
If you can't fix the query somehow, Distinct is your only option.

Is there an OR clause in LINQ?

I am trying to query an XML document for the specific records that I need. I know that the line containing the "or where" case below is incorrect, but I'm hoping it will illustrate what I am trying to accomplish. Can you do a conditional where clause on two seperate properties?
XDocument xd = XDocument.Load("CardData.xml");
SearchList.ItemsSource = from x in xd.Descendants("card")
where x.Element("title").Value.ToUpper().Contains(searchterm.ToUpper())
or where x.Element("id").Value.Contains(searchterm)
select new Card
{
Title = x.Element("title").Value
};
Yes - simply use the boolean or || and combine your conditions into one Where clause:
where x.Element("title").Value.ToUpper().Contains(searchterm.ToUpper()) ||
x.Element("id").Value.Contains(searchterm)
Also note just as a minor optimization, I would pre-compute some of the operations you currently have in your Where clause so they are not performed on every item in the list - probably doesn't matter but it might when you have a lot of elements (and is just a good habit to get into in my opinion):
string searchTermUpperCase = searchterm.ToUpper();
SearchList.ItemsSource = from x in xd.Descendants("card")
where x.Element("title").Value.ToUpper().Contains(searchTermUpperCase)
or where x.Element("id").Value.Contains(searchterm)
..

LINQ Grouping help

I have a database table that holds parent and child records much like a Categories table. The ParentID field of this table holds the ID of that record's parent record...
My table columns are: SectionID, Title, Number, ParentID, Active
I only plan to allow my parent to child relationship go two levels deep. So I have a section and a sub section and that it.
I need to output this data into my MVC view page in an outline fashion like so...
Section 1
Sub-Section 1 of 1
Sub-Section 2 of 1
Sub-Section 3 of 1
Section 2
Sub-Section 1 of 2
Sub-Section 2 of 2
Sub-Section 3 of 2
Section 3
I am using Entity Framework 4.0 and MVC 2.0 and have never tried something like this with LINQ. I have a FK set up on the section table mapping the ParentID back to the SectionID hoping EF would create a complex "Section" type with the Sub-Sections as a property of type list of Sections but maybe I did not set things up correctly.
So I am guessing I can still get the end result using a LINQ query. Can someone point me to some sample code that could provide a solution or possibly a hint in the right direction?
Update:
I was able to straighten out my EDMX so that I can get the sub-sections for each section as a property of type list, but now I realize I need to sort the related entities.
var sections = from section in dataContext.Sections
where section.Active == true && section.ParentID == 0
orderby section.Number
select new Section
{
SectionID = section.SectionID,
Title = section.Title,
Number = section.Number,
ParentID = section.ParentID,
Timestamp = section.Timestamp,
Active = section.Active,
Children = section.Children.OrderBy(c => c.Number)
};
produces the following error.
Cannot implicitly convert type 'System.Linq.IOrderedEnumerable' to 'System.Data.Objects.DataClasses.EntityCollection'
Your model has two navigation properties Sections1 and Section1. Rename the first one to Children and the second one to Parent.
Depending on whether you have a root Section or perhaps have each top-level section parented to itself (or instead make parent nullable?), your query might look something like:-
// assume top sections are ones where parent == self
var topSections = context.Sections.Where(section => section.ParentId == SectionId);
// now put them in order (might have multiple orderings depending on input, pick one)
topSections = topSections.OrderBy(section => section.Title);
// now get the children in order using an anonymous type for the projection
var result = topSections.Select(section => new {top = section, children = section.Children.OrderBy(child => child.Title)});
For some linq examples:
http://msdn.microsoft.com/en-us/vcsharp/aa336746.aspx
This covers pretty much all of the linq operations, have a look in particular at GroupBy. The key is to understand the input and output of each piece in order to orchestrate several in series and there is no shortcut but to learn what they do so you know what's at hand. Linq expressions are just combinations of these operations with some syntactic sugar.

Resources