LINQ table enumeration with column enumeration - c#

How do you get a list of all the tables and use that list to enumerate the columns?
I've found posts that describe one or the other, but not both.
My net-result is I want to generate a static class which contains names of all the columns in each tables so I could, for example, do:
comboBoxFoo.DisplayMember = SomeNamespace.SomeTable.SomeDisplayColumnName;
comboBoxFoo.ValueMember = SomeNamespace.SomeTable.SomeIDColumnName;
comboBoxFoo.DataSource = dingo;
I'm currently using this method which while it works, it means I have to manually create my tables in a list.
I have a seperate command line project which generates the SomeNameSpace.SomeTable class manually and I add the generated class file in to the project.
Ideally, if I could loop through via a foreach of tables and do something like this:
foreach(var table in someTableNumerationMethodForAGivenContext())
{
var columnList = databaseContext.ColumnNames<someTable>();
foreach(var columnData in columnList)
{
DoJazz(columnData.Name);
}
}
Is there a better way to do this other than manually have to do the databaseContext.ColumnNames() ?
Edit 1:
We're using LinqToSQL. Moving to ADO.NET also an option on the table, but at the moment we have no pressing need to.
Edit 2:
I know L2S does databinding but what I'm after is getting a list of column names as strings from a table. L2S doesn't offer this or it's not apparent on my side.
I'd like to do something like: SomeTable.SomeColumn.ToString() or something. SubSonic has this.
Final:
Thanks everyone. all are very good answers and lead me to the answer. You guys rock!

Nazadus,
Is this what you are looking for?
LINQ to SQL Trick: Get all Table [and Column] Names:
http://blogs.msdn.com/jomo_fisher/archive/2007/07/30/linq-to-sql-trick-get-all-table-names.aspx

What you are describing is essentially an ORM
Linq to SQL is an ORM that will create prototype c# classes for you that contain the information you are describing. It has excellent support for the kind of data binding that you have illustrated.

I think you are looking for this.
DataContext.Mapping.GetTable(yourTable).RowType.DataMemebers()

I can think of two ways to do this.
A) Use SMO to get all the tables / columns in a database. You need to reference:
Microsoft.SqlServer.ConnectionInfo
Microsoft.SqlServer.Management.Sdk.Sfc
Microsoft.SqlServer.Smo
Then, you can do something like this:
ServerConnection connection = new ServerConnection(".");
Server server = new Server(connection);
Database db = server.Databases["Northwind"];
foreach (Table table in db.Tables)
{
foreach (Column column in table.Columns)
{
Console.WriteLine("Table: {0}, Column: {1}",table.Name,column.Name);
}
}
}
B) Use reflection to reflect over your assembly with the dataclasses generated by Linq to Sql. Anything with a Table attribute is a table, and anything with a Column attribute is a column. Let me know if you need a sample...

Related

Get SYSTEM_TIME information from a temporal table on Entity Framework code first method

I created my temporal table following instructions on this link "Cutting Edge - Soft Updates with Temporal Tables"
The procedure generally takes two steps:
create the regular table; this is just the kind of work that Code First usually does
alter the table by adding SysStartTime, SysEndTime columns and turning on the SYSTEM_VERSIONING setting
Everything looks good so far.
However, please note that the entity class doesn't have SysStartTime property and SysEndTime property as they are added later. This gives me trouble as I need to get information of SysStartTime from table.
My question is: How can I get it with Entity Framework?
The link also says:
In EF 6, you can only leverage the SqlQuery method of the DbSet class:
using (var db = new EF6Context())
{
var current = db.Bookings.Single(b => b.Id == 1);
var time = DateTime.Now.AddMinutes(-5);
var old = db.Bookings
.SqlQuery("SELECT * FROM dbo.Bookings
FOR SYSTEM_TIME AS OF {0} WHERE Id = 1", time)
.SingleOrDefault();
}
Note that for EF 6, the column names returned in the query need to match the property names on the class. This is because SqlQuery doesn’t use mappings. If column and property names don’t match, then you’d need to alias the columns in the SELECT list, rather than just SELECT *.
I have no clue how to do this or if it solves my problem. Does anyone have any experience on this?
I can think of one solution is to added an extra column AppliedTime on my table by adding AppliedTime to my entity class. It has (almost, but good enough for me) same value as SysStartTime.
Another solution could be use plain SQL to query the table directly.
Thanks.
I have been worked on this one and found a solution. It is actually quite simple. Just use Database.SqlQuery Method
DateTime time = context.Database.SqlQuery<DateTime>("SELECT SysStartTime
FROM dbo.Calibration
WHERE CalibrationID = 1")
.SingleOrDefault();
See Also: Raw SQL Queries

Linq select where has at least one entry in another table

I have the following structure that I wan't to query using Linq, specifically Linq to Entities (Enitity Framework).
Table1: RouteMeta
Table2: SitePage
Multiple SitePages can link to the same RouteMeta.
I'm querying the Route Meta to select a number of rows. I'm using a generic repository, currently like this:
return r.Find().ToList();
There's nothing special about it - the Find method accepts an optional linq expression, so I could do something like this:
return r.Find(x => x.Status=1).ToList();
However, what I actually want to do is to select rows from RouteMeta where at least one linked row exists in SitePages with a property IsPublished = true.
return r.Find(x => x.SitePages("where y => y.IsPublished = true");
Obviously, the above isn't correct, I'm just trying to explain the scenario better.
Any advice appreciated.
try something like
return r.Find(x=>x.Sitepages.Any(y=>y.Published))?
I'd also suggesting using a profiler if possible to check that this translates properly into SQL. It probably should do but it depends on how your repository works.

Looping through tables in Entity Framework 6

sorry for the simple question. I'm new at this. I have an entity model with several tables and I'd like to get a list of the tables, then I'd like to get the contents of a column from the tables.
For example, I have tables of subjects: Biology, Chemistry and Physics, each with a column className (among other columns). I'd like to loop through the tables, get the name then get the contents under that column since I need to ToList() it.
I want to do something like this:
for each (table in myEntityModel)
{
Get tableName from table
Get contents under className from table
}
I've tried using metadataworkspace, and I got a list of tableName, but that didn't help me too much in getting the contents of each table. I'm able to query individual tables, but I don't know how to change tables once I do. If I use: from r in myEntity.Biology select{...}, I can't change the entityset I'm referring to.
Oh, and, if the context of what I'm doing helps, I'm trying to build an accordion with the help of Ajax Control Toolkit 16.1 in Visual Studios 2015. I'm using Entity Framework 6.0. The subject name is going to be the headercontainer and the list of classes will be added as a gridview into the accordion pane. I'm new to C#, Visual Studios, databases, queries, entity models and almost everything I'm working with, but feel free to use as much jargon as you'd like. I'll google it if something confuses me. Thank you!
It's not efficient, because it loads the entire table in memory, but you can do this:
var myEntityModel = new MyEntityModel(); //your context
var dbSets = myEntityModel.GetType().GetProperties().Where(p => p.PropertyType.Name.StartsWith("DbSet")); //get Dbset<T>
foreach (var dbSetProps in dbSets)
{
var dbSet = dbSetProps.GetValue(myEntityModel, null);
var dbSetType = dbSet.GetType().GetGenericArguments().First();
var classNameProp = dbSetType.GetProperty("className");// i did not undestand, you want classes with className property?
if (classNameProp != null)
{
var contents = ((IEnumerable) dbSet).Cast<object>().ToArray();//Get The Contents of table
}

Cycle Through Sql Columns

I am working with a gridview in C# and I am wondering if there is an effective way to use one data source instead of three. Right now I have an if statement that selects the Data Source based off the value in a dropdownlist, ddlType.
if (ddlType.Text == "Confirmation")
gvMailMergeExport.DataSourceID = "SqlDSConfirmation";
else if (ddlType.Text == "Cancellation")
gvMailMergeExport.DataSourceID = "SqlDSCancellation";
else
gvMailMergeExport.DataSourceID = "SqlDSPreArrival";
Because each Database needs to look at a different column in the same table to decide which data to show.
The three columns being used are ConfirmationEmail, CancellationEmail, and PreArrivalEmail.
Each of these three columns is a bit value and I only display the rows where the correct column has a '0' for it's value.
So question: is there anything like #ColumnName = 0 that would work for this?
Thank you.
I've never used SQLDataSources, but if you want to go the more custom route, you could build out your query (or use LINQ to SQL or LINQ to Entity Framework) with the custom where clause based on the user selection.
Which technology are you more familiar with? LINQ would be better, but I can give an answer in ADO.NET as well (SqlConnection, SqlCommand, etc).
So the LINQ would be relatively simple. After setting up your LINQ to Entities (EDMX) or LINQ to SQL (DBML) (I'd do the EDMX, because L2S is no longer supported in forward maintenance by MSFT). With an existing DB, it's very easy, drag and drop.
The code would look like this:
using(var context = new LinqDbContext())
{
var results = context.Tablename;
if(limitByConfEmail)
{
results = results.Where(data => data.ConfirmationEmail == true);
}
// do your elses here
gridview.DataSource = results;
gridview.DataBind();
}

Accessing foreign keys through LINQ

I have a setup on SQL Server 2008. I've got three tables. One has a string identifier as a primary key. The second table holds indices into an attribute table. The third simply holds foreign keys into both tables- so that the attributes themselves aren't held in the first table but are instead referred to. Apparently this is common in database normalization, although it is still insane because I know that, since the key is a string, it would take a maximum of 1 attribute per 30 first table room entries to yield a space benefit, let alone the time and complexity problems.
How can I write a LINQ to SQL query to only return values from the first table, such that they hold only specific attributes, as defined in the list in the second table? I attempted to use a Join or GroupJoin, but apparently SQL Server 2008 cannot use a Tuple as the return value.
"I attempted to use a Join or
GroupJoin, but apparently SQL Server
2008 cannot use a Tuple as the return
value".
You can use anonymous types instead of Tuples which are supported by Linq2SQL.
IE:
from x in source group x by new {x.Field1, x.Field2}
I'm not quite clear what you're asking for. Some code might help. Are you looking for something like this?
var q = from i in ctx.Items
select new
{
i.ItemId,
i.ItemTitle,
Attributes = from map in i.AttributeMaps
select map.Attribute
};
I use this page all the time for figuring out complex linq queries when I know the sql approach I want to use.
VB http://msdn.microsoft.com/en-us/vbasic/bb688085
C# http://msdn.microsoft.com/en-us/vcsharp/aa336746.aspx
If you know how to write the sql query to get the data you want then this will show you how to get the same result translating it into linq syntax.

Categories