Looping through tables in Entity Framework 6 - c#

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
}

Related

get related data from ms dynamics crm using XRM SDK

I'm trying to retrieve data from crm in a .net application, using the SDK.
I've managed to do simple queries to retrieve lists, but I would now like to get the related entities with items, rather than the ids.
I have tried things like
QueryExpression query = new QueryExpression
{
EntityName = "opportunity",
....
LinkEntity linkEntityAccount = new LinkEntity()
{
LinkFromEntityName = "opportunity",
LinkFromAttributeName = "opportunityid",
LinkToEntityName = "serviceappointment",
LinkToAttributeName = "regardingobjectid",
JoinOperator = JoinOperator.Inner,
Columns = new ColumnSet(new string[] { "scheduledstart", "scheduledend" }),
EntityAlias = "service"
};
query.LinkEntities.Add(linkEntityAccount);
(This will return a collection of entities from the opportunity table)
However the LinkedEntities just put the two columns in the returns entities.
What i would like is (say for this example) is a entity.serviceappointment to be the the entity containing the service appointment entity/data. Instead of in entity there being fields such as service.scheduledstart and service.scheduledend
I have looked at the Relationship and RelationshipQueryCollection things in the SDK but i have been unable to setup a query that will do the query, without first getting the opportunity entities. But it looks like that maybe what I need? I'm not sure.
Is this even possible? Or should I just continue to query entities individually?
Thanks
In the QueryExpression the LinkEntity represents a join. That's why the fields of the joined table are in the Entity row. They can be distinguished from the 'real' entity attributes by the fact that their names are prefixed (including a dot) and their values are wrapped in an AliasedValue object.
It is possible to unwrap them and create strong typed Entity objects, but you will need to write the code yourself.
Alternatively you can consider a few other options:
Query for serviceappointment records and join the opportunity records.
Retrieve opportunity records one by one using the RetrieveRequest and include the query for the related service appointments in the request. (See also this discussion on StackOverflow.)
Create an Action returning all data you need in a convenient OrganizationResponse.
There's no automatic way to get the entire linked entity data (as an Entity object) that I know of (that's not to say it's impossible, mind you).
But I think it'd be a lot easier to just query the data you need in another request.
Find the list of opportunities you need
Use the regarding object IDs as the parameter of an "IN" filter for the second query.

C# LINQ to Entities - Select specified Data from two tables, populate existing Model Classes

I have a database and am using C# LINQ to Entities using Query Syntax.
Each DB table has it's own Entity Framework generated model class, the DB tables and model classes are named Release and Version (there are others but this is my immediate problem).
I'm trying to load specific data into these model classes based on a query.
Essentially I want every Release column & row, along with its associated Version records populated in the Navigation Property Release.Versions.
However, two crucial points here:
1) I only want certain 'Version' properties to be populated from the Query
(I only need some of the data for use in an Overview page - I can't see the point of dragging back all the data (which could be quite sizeable) if I am not using it).
2) I want the query to populate the already existing Model classes of Release and Version.
(Release.Versions Navigation property being populated with the Version records with cherry picked data from point 1 above)
All this I could do in a long winded way with Stored Procedures - no issue, but thought EF Linq would be quicker. Ha. Ha. Haaaa.
So:
Release.ID <---- Primary Key
Release.Col_1 <---- Other Properties (or columns)
Release.Col_2
Release.Col_3
Release.Versions <---- Navigation Property to collection of Version records for each Release.
Version.ID <---- Primary Key
Version.Release_ID <---- Foreign Key to Release Table
Version.Col_1 <---- Many properties, just want first 4 properties obtained from DB.
Version.Col_2
Version.Col_3
Version.Col_4
Version.Col_5
Version.Col_x...
I just can't get the syntax right.
This is what I have (I've tried many other variants but nothing as simple as I remember it being):
var query = (from r in context.Releases
join v in context.Versions on r.ID equals v.Release_ID
select r).ToList();
returnedRecords= new ObservableCollection<Model.Release>(query);
I seem to remember having to use the select new Release { x,y,z } and then a nested new Version { x, y, z} - but cannot for the life of me remember how to do it, or how to get it to populate the Navigation property Versions within the Release class.
Maybe using Lambda syntax???????
EDIT:
OK, it appears I cannot do what I thought I could do.
So, I'm not going to use Query Syntax as most of the tutorials and documentation I can find are in Method Syntax. Plus I think Include only works with Method syntax, so seems a bit pointless using Query Syntax.
Answer marked as correct is how I loaded the Navigation Properties.
You can simply load 'foreign' records for your table by using Include method.
var x = context.Releases.Include("Versions").ToList();
If you want the query to return the model class Release with a nested Version class, you can do it like this:
var query = (from r in context.Releases
join v in context.Versions on r.ID equals v.Release_ID
select new Release
{
releaseColumn1 = r.releaseColumn1,
releaseColumn12 = r.releaseColumn2,
releaseVersion = new Version
{
versionColumn1 = v.versionColumn1,
versionColumn2 = v.versionColumn2
}
}).ToList();

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();
}

Retrieving a tree structure from a database using LINQ

I have an organization chart tree structure stored in a database.
Is is something like
ID (int);
Name (String);
ParentID (int)
In C# it is represented by a class like
class Employee
{
int ID,
string Name,
IList < Employee> Subs
}
I am wondering how is the best way to retrieve these values from the database to fill up the C# Objects using LINQ (I am using Entity Framework)
There must be something better than making a call to get the top level then making repeated calls to get subs and so on.
How best to do it?
You can build a stored proc that has built in recursion. Take a look at http://msdn.microsoft.com/en-us/library/ms190766.aspx for more info on Common Table Expressions in SQL Server
You might want to find a different (better?) way to model your data. http://www.sqlteam.com/article/more-trees-hierarchies-in-sql lists a popular way of modeling hierarchical data in a database. Changing the modeling can allow you to create queries that can be expressed without recursion.
If you're using SQL Server 2008, you could make use of the new HIERARCHYID feature.
Organizations have struggled in past
with the representation of tree like
structures in the databases, lot of
joins lots of complex logic goes into
the place, whether it is organization
hierarchy or defining a BOM (Bill of
Materials) where one finished product
is dependent on another semi finished
materials / kit items and these kit
items are dependent on another semi
finished items or raw materials.
SQL Server 2008 has the solution to
the problem where we store the entire
hierarchy in the data type
HierarchyID. HierarchyID is a variable
length system data type. HierarchyID
is used to locate the position in the
hierarchy of the element like Scott is
the CEO and Mark as well as Ravi
reports to Scott and Ben and Laura
report to Mark, Vijay, James and Frank
report to Ravi.
So use the new functions available, and simply return the data you need without using LINQ. The drawback is you'll need to use UDF or stored procedures for anything beyond a simple root query:
SELECT #Manager = CAST('/1/' AS hierarchyid)
SELECT #FirstChild = #Manager.GetDescendant(NULL,NULL)
I'd add a field to the entity to include the parent ID, then I'd pull the whole table into memory leaving the List subs null. Id then iterate through the objects and populate the list using linq to objects. Only one DB query so should be reasonable.
An Entity Framework query should allow you to include related entity sets, though in a unary relationship, not sure how it would work...
Check this out for more information on that: http://msdn.microsoft.com/en-us/library/bb896272.aspx
Well... even with LINQ you will need two queries, because any single query will duplicate the main employee and thus will result in multiple employees (that are really the same) being created... However, you can hide this a bit with linq when you create the object, that's when you would execute the second query, something like this:
var v = from u in TblUsers
select new {
SupervisorName = u.DisplayName,
Subs = (from sub in TblUsers where sub.SupervisorID.Value==u.UserID select sub.DisplayName).ToList()
};

LINQ table enumeration with column enumeration

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...

Categories