1

Let's say my query returns a DataTable which is a list of email addresses, a single varchar column called "email"; these emails are authorized to do something.

jane@doe.com
mike@foo.com
donald@duck.com

And the current logged in user is harry@houdini.com. He's not authorized. He's not on the list

Is it possible to iterate the DataRows using Linq and return a boolean false?

Or to return an object which is null or Nothing or empty?

In essence, I would like to know the Linq version of

 Authorized = List.Contains( "harry@houdini.com")

I would really like to know how to do this both in C# and VB.

Thanks

Tim
  • 8,669
  • 31
  • 105
  • 183
  • Use the `Any()` method to check whether any item matches your predicate. – SLaks Jan 10 '18 at 20:10
  • The code that you showed *is* a valid LINQ solution to the problem. It compiles and runs as is. – Servy Jan 10 '18 at 20:11
  • @SLaks: I'm getting an error that `'Any' is not a member of EnumerableRowCollection(Of DataRow).` I think I may have imported the wrong library (DataSetExtensions) ? No, System.Data.DataTableExtensions has the same error. – Tim Jan 10 '18 at 20:41
  • did you Imports `System.Linq` ? – Ehsan Ullah Nazir Jan 10 '18 at 20:47

2 Answers2

2

Any is probably cleaner here:

bool exists = dataTable.AsEnumerable()
                       .Any(r => "harry@houdini.com".Equals(r[0]));

You could project the column to a collection of strings and use Contains, but it seems like overkill here.

Or define a primary key and use the native Contains method on DataRowCollection:

dataTable.PrimaryKey = dataTable.Columns[0];
bool exists = dataTable.Rows.Contains("harry@houdini.com");
D Stanley
  • 149,601
  • 11
  • 178
  • 240
  • 1
    Why do you think that "where any item is equal to this item" is clearer than, using `Contains` when you want to find out if an item is contained in a sequence? There's no need to use a collection to use `Contains`. – Servy Jan 10 '18 at 20:12
  • 2
    The source "collection" is a `DataTable`, so `Contains` would not work without a primary key or a custom equality comparer for `DataRow`. – D Stanley Jan 10 '18 at 20:13
2

Here is working example with DataTable as follows

In C#

        DataTable dt = new DataTable();
        dt.Columns.Add("emails");
        dt.Rows.Add("jane@doe.com");
        dt.Rows.Add("mike@foo.com");
        dt.Rows.Add("donald@duck.com");

        var authorized = dt.AsEnumerable().Any(s => s[0].Equals("mike@foo.com")); //returns True
        var notAuthorized = dt.AsEnumerable().Any(s => s[0].Equals("harry@houdini.com"));  //returns False

In VB (Converted online)

        Dim dt As DataTable = New DataTable
        dt.Columns.Add("emails")
        dt.Rows.Add("jane@doe.com")
        dt.Rows.Add("mike@foo.com")
        dt.Rows.Add("donald@duck.com")
        Dim authorized As var = dt.AsEnumerable.Any(() => {  }, 
           s(0).Equals("mike@foo.com"))
        Dim notAuthorized As var = dt.AsEnumerable.Any(() => {  }, 
           s(0).Equals("harry@houdini.com"))
Ehsan Ullah Nazir
  • 1,827
  • 1
  • 14
  • 20
  • I am trying to translate this to VB: `Dim authorized as Boolean = dt.AsEnumerable().Any(Function(s) s(0).Equals("mike@foo.com"))`. I get this error: " 'Any' is not a member of 'EnumerableRowCollection(Of DataRow)". – Tim Jan 10 '18 at 20:37
  • did you `Imports System.Linq` ? – Ehsan Ullah Nazir Jan 10 '18 at 20:40
  • Aha, I thought the DataTableExtensions had all that was needed. Importing Linq. Error gone. After converting s(0).ToString.ToUpper the `Any` comparison returns true. Thanks. – Tim Jan 10 '18 at 20:52
  • Thanks but this was converted this online , Just to give idea to OP. – Ehsan Ullah Nazir Jan 10 '18 at 21:07