LINQ staat voor Language Integrated Query en is bedoeld om op een uniforme manier gegevens te halen uit 'een bak met data'. Daarbij moet het niet uitmaken wat voor 'bak' we gebruiken. Naast de standaard implementaties kwam ik laatst een erg leuke toevoeging tegen: LINQtoTwitter.

LINQ staat voor Language Integrated Query en is bedoeld om op een uniforme manier gegevens te halen uit 'een bak met data'. Daarbij moet het niet uitmaken wat voor 'bak' we gebruiken. Naast de standaard implementaties kwam ik laatst een erg leuke toevoeging tegen: LINQtoTwitter.
LINQ
We kennen al LINQtoObjects, LINQtoXML, LINQtoSQL, LINQtoEntities. Stuk voor stuk super handig en zeker het bestuderen waard. Kijk ook eens naar mijn blog over de LINQ presentatie die ik op de DevDays 2010 heb verzorgd.
Codeplex open source project
Codeplex is de Open Source Community van Microsoft en hier zijn veel leuke projecten te vinden. Hier vond ik ook LINQ to Twitter: http://linqtotwitter.codeplex.com, ofwel: een schil over de twitter API zodat je met LINQ queries kun zoeken naar tweets, personen, statussen enz. Tevens kun je ook tweets plaatsen en updates doen van bijvoorbeeld een profielfoto. De mogelijkheden zijn eindeloos. Bij het project staan ook diverse test applicaties, dus je kunt direct aan de gang.
Twitter Reader
Maar laten we beginnen bij het begin: Een applicatie die opzoek gaat naar tweets die geplaatst zijn in een bepaalde periode en een bepaalde tekst bevatten.
Hiervoor maak ik een WPF applicatie. Eerst moet de LINQtoTwitter.dll gereferenced worden. De user inerface ziet er als volgt uit. De DatePickers zijn windowsForms controls en dienen daarom in een <WindowsFormsHost> geplaatst te worden.
LINQtoTwitter
De XAML:
<Window x:Class="TAMitTweetReader.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:wf="clr-namespace:System.Windows.Forms;assembly=System.Windows.Forms"
        Title="Truly Amazing Master it Tweet Reader" Height="450" Width="750" Closing="Window_Closing">
    <Grid>
        <WindowsFormsHost Height="25" Margin="282,59,250,0" Name="windowsFormsHost1" VerticalAlignment="Top">
            <wf:DateTimePicker x:Name="dtpFromDate" />
        </WindowsFormsHost>
        <WindowsFormsHost Height="25" HorizontalAlignment="Right" Margin="0,59,25,0" Name="windowsFormsHost2" VerticalAlignment="Top" Width="180" >
            <wf:DateTimePicker x:Name="dtpToDate" />
        </WindowsFormsHost>
        <Button Content="Zoeken" Height="23" HorizontalAlignment="Left" Margin="28,21,0,0" Name="btnSearch" VerticalAlignment="Top" Width="113" Click="btnSearch_Click" />
        <CheckBox Content="Default" Height="16" HorizontalAlignment="Left" Margin="28,59,0,0" Name="cbDefault" VerticalAlignment="Top" IsChecked="False" Checked="cbDefault_Checked" Unchecked="cbDefault_Unchecked" />
        <Label Content="Van:" Height="28" HorizontalAlignment="Left" Margin="243,59,0,0" Name="lblDateFrom" VerticalAlignment="Top" />
        <Label Content="Tot:" Height="28" HorizontalAlignment="Right" Margin="0,59,211,0" Name="lblDateTo" VerticalAlignment="Top" />
        <Label Content="Zoekterm:" Height="28" HorizontalAlignment="Left" Margin="212,16,0,0" Name="label1" VerticalAlignment="Top" />
        <TextBox Height="23" Margin="282,18,25,0" Name="tbSearchTerm" VerticalAlignment="Top" />
        <StatusBar Name="stsBar" Height="39" VerticalAlignment="Bottom">
            <Label Name="lblStatus">Klaar</Label>
        </StatusBar>
        <ListBox Margin="28,96,25,74" Name="lbTweets" ItemsSource="{Binding}" HorizontalContentAlignment="Stretch" VerticalContentAlignment="Stretch">
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <Border BorderThickness="1" BorderBrush="#cccccc" MinHeight="70" Background="#eeeeee" >
                        <StackPanel Orientation="Horizontal">
                            <Image Height="48" Margin="10,5,30,5" Source="{Binding Path=Author.AuthorImage}"/>
                            <StackPanel Orientation="Vertical" Width="500" >
                                <StackPanel Orientation="Horizontal">
                                    <TextBlock Foreground="#888888" Text="{Binding Path=Date}" />
                                    <TextBlock FontWeight="Bold" Text="{Binding Path=Author.Name}" />
                                </StackPanel>
                                <TextBlock Text="{Binding Path=Title}" TextWrapping="Wrap"  />
                            </StackPanel>
                        </StackPanel>
                    </Border>
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>
        <Button Content="Print Labels" Height="23" HorizontalAlignment="Left" Margin="28,343,0,0" Name="btnPrint" VerticalAlignment="Top" Width="113" Click="btnPrint_Click" />
    </Grid>
</Window>
Je ziet dat ik een ItemTemplate heb gemaakt voor de ListBox. Hierin bepaal ik de layout van de tweets op in de listbox. Zo kunnen de foto, de gebruiker en het bericht netjes bijelkaar staan.
Na het toevoegen van de ‘using LinqToTwitter;’ in de C# file kunnen we de LINQ query gaan bouwen. De ‘bak met data’ is in geval dus Twitter. Hiervoor moeten we een TwitterContext aanmaken.
List<SearchItem> Entries;
var twitterCtx = new TwitterContext();
var queryResults =
    (from search in twitterCtx.Search
     where search.Type == SearchType.Search &&
           search.Query == tbSearchTerm.Text &&
           search.Since == dtpFromDate.Value && // remember to use Date property
           search.Until == dtpToDate.Value // remember to use Date property
     select search);
Entries =
   (from result in queryResults
    from atomEntry in result.Entries
    select new SearchItem
    {
        Title = atomEntry.Title,
        Abstract = atomEntry.Content,
        Date = atomEntry.Published,
        Source = atomEntry.Source,
        Url = atomEntry.Alternate,
        Author = new AuthorInfo
        {
            AuthorImage = atomEntry.Image,
            Url = atomEntry.Author.URI,
            Name = atomEntry.Author.Name
        }
                }).ToList();
lbTweets.DataContext = Entries;
De tweets worden opgehaald en de gegevens van de gebruiker worden erbij gezocht. Uiteindelijk gebruik ik Databinding om de gevonden tweets aan de listbox te koppelen. Je ziet dat er nog 2 classes gebruikt worden die niet standaard zijn: AuthorInfo en SearchItem. Deze zien er als volgt uit.
public class SearchItem
    {
        public string Title { get; set; }
        public string Abstract { get; set; }
        public DateTime Date { get; set; }
        public string Extract { get; set; }
        public List<LocatedItem> Locations { get; set; }
        public string Source { get; set; }
        public string Url { get; set; }
        public AuthorInfo Author { get; set; }
    };
    public class AuthorInfo
    {
        public string AuthorImage { get; set; }
        public string Url { get; set; }
        public string Name { get; set; }
    }
NuGet
LINQ to Twitter is ook via NuGet te verkrijgen. http://nuget.org/List/Packages/linqtotwitter Met deze extentie voor Visual Studio wordt het erg gemakkelijk om diversie open source projecten in je visual studio te onder te brengen. Zeker de moeite waard om een keer in te duiken. Meer informatie over NuGet vind je op: http://geekswithblogs.net/WinAZ/archive/2011/03/18/a-gentle-introduction-to-nuget.aspx