I am using null
as a sentinel/trip value to break out of foreach:
public static DataTable ExecuteQuery(string sql)
{
var conn = new SqlConnection(EnvironmentVariables.GetDbConnectionString());
var adapter = new SqlDataAdapter(sql, conn);
var table = new DataTable();
adapter.Fill(table);
return table;
}
private VacantSummaryPage SelectPropertyFromDb(string sql)
{
VacantProperty vacantProperty = null;
List<VacantProperty> vacantProperties = GetProperties();
foreach (DataRow row in SqlServer.ExecuteQuery(sql).Rows)
{
vacantProperty = vacantProperties.Find(v => v.GetTitle().Contains(row["PartialStreetAddress"].ToString()));
if (vacantProperty != null) break;
}
vacantProperty.Select();
return new VacantSummaryPage(driver);
}
What it does is once a vacantProperty
is matched where it is then no longer null, break out of the loop and Select()
that property.
You can write a "single line" instruction using a LINQ comprehension query (SQL-like syntax):
private VacantSummaryPage SelectPropertyFromDb(string sql)
{
var query = from row in SqlServer.ExecuteQuery(sql).Rows.Cast<DataRow>()
from property in GetProperties()
where property.GetTitle().Contains(row["PartialStreetAddress"].ToString())
select property;
vacantProperty = query.FirstOrDefault();
if ( vacantProperty != null )
vacantProperty.Select();
return new VacantSummaryPage(driver);
}
Using only First
will raise an exception if not found, so with FirstOrDefault
we can control the not found case, unless exception control is preferred.
Here the query itself is deferred, and it is evaluated when calling the First/FirstOrDefault or a ToList() for example.
LINQ deferred (or immediate?) execution
Deferred Execution of LINQ Query
LINQ: Why is it called "Comprehension Syntax"
Query Syntax and Method Syntax in LINQ (C#)
LINQ Query Syntax (Comprehensive)
Good to know
TypedTableBase used by DataSet allow to directly implements IEnumerable<DataRow>
and so also Typed DataSets.