Pass the table and column dynamically in dynamic LINQ - c#

I searched a lot, but couldn't find what I was looking exactly. This may be very simple. Normally in LINQ we write the select query like this:
var entityModel = new StudentEntities();
var dept = (from a in entityModel.STUDENT where a.NAME != null select a.DEPARTMENT).Distinct().OrderBy(w => w);
//STUDENT- table, NAME-column name, DEPARTMENT-column name
How to write the same query using dynamic LINQ? Here the table name and column name names will be selected from either some winForm controls (textbox/combobox) or string. Tried this:
var dept = "(from a in entityModel." + tableName + "where a." + cbo1.Text.ToString + "!= null select a."+cbo2.Text.ToString +").Distinct().OrderBy(w => w)";
This is not working. Can anyone point me to the right direction, please?

You can't do that. You need to generate your dynamic SQL and run it over your database.
There's this library: Dynamic LINQ, but it isn't as dynamic as you want.

Related

get column name in addition to the result (oracle)

I have a program in c# (asp.net environment) that dynamically runs ORACLE queries.
the queries can be like:
select * from app_costumers;
select a.first_name, a.last name, b.salary from app_costumers inner join app_costs b on a.id = b.id;
(As you can see, this is sometimes about a single table and sometimes more.
Sometimes writing the column names and sometimes using only in "*").
until now, I returned only the results,
But now I need to return the names of the results columns.
Do you have any idea how to do this?
(I can't use something like this:
SELECT column_name FROM user_tab_cols WHERE table_name = UPPER ('app_costumers');
Because it only fits for one table ...).
Thank you
You can use reader.GetName(i), for example:
var reader = cmd.ExecuteReader();
var columns = new List<string>();
for(int i=0;i<reader.FieldCount;i++)
{
columns.Add(reader.GetName(i));
}

Convert table name (in string) to use it in the LINQ query : C#, Entity Framework

I have a list of table names in form of strings. I want to loop through the list and use the table name in the LINQ query:
var db = new SomeContext();
// for a single table I can use the LINQ query as
var res = from q in db.Table
where ......
select q;
and it works just fine.
The above approach is hard coding. I need a generic solution for this to loop through multiple tables whose names are stored in a list.
// list of string containing table names
List<stringtableNames = [Get the table list from some source]
// not a problem here
loop through the table names and for each name execute a LINQ query as shown below
foreach(string table in tableNames)
{
var queryRes = from t in table
where <some_condition>
select t;
}
In the above statements "from t in table" above is not valid as "table" is a string. I need actual table object reference to use.
Need help on how do I go about doing that.
You can use the DbContext.Set method:
Set(System.Type.GetType("TableName"))
Above sentence will return a non generic DbSet. So, you will not be able to query with linq as usual. But you can use dynamic linq. ScottGu will explain it better than me.
Please, check this thread for other solutions.
In EF you can execute SQL Code.
In this example i use EF with SQL (String)
var db = new SomeContext();
var list = db.ExecuteStoreQuery<Obj>(Obj.sql);
class Obj
{
public const string sql = #"select [tbl].[field] from [tbl]";
}
select, where, from is one way to define LINQ but You can use it if you have a list of elements (IEnumerable<T> for example), but You have only name of Your table
I think You have to create a regular SQL query
foreach(string table in tableNames)
{
var query =$"select * from {table} where <some_condition>";
var list = db.ExecuteStoreQuery<Obj>(query);
}
In EF You can execute regular query

How to get Column Names with EF6/MySQL

I am using EntityFramework v6.1 with MySql.Data.Entity.EF6 v 6.8.3.0.
I am attempting to get the "Headers" or "Column Names" for data inside tables. I have a table called "dbases" and I need to get the Column Names from within ADO.NET, please help!
using (var connection = new hyperion_collectionsmaxEntities())
{
var portfolios = connection.portfolios.ToList();
portfolios.ForEach(o => comboBox1.Items.Add(o.portfolio1));
var statuses = connection.adminstatus.ToList();
statuses.ForEach(o => chkLstBoxStatuses.Items.Add(o.statusname));
//var headers = connection.dbases ?? <~~~
}
One way to get at the column names is to query to MetaTables:
SELECT COLUMN_NAME, TABLE_NAME
FROM information_schema.COLUMNS
WHERE information_schema.COLUMNS.table_schema = 'dbases';
There are a lot of interesting data there. For simply getting at the Column Name and the (default) Header you can use the DataTable.Column's properties:
yourTable.Columns[columnIndex].ColumnName
yourTable.Columns[columnIndex].Caption
If EF has special ways I don't know about them.. but in the end imo the data should go into the DataTable..

Linq to SQL JOIN?

I am trying to query names in one table and then use that result to pull the master records into a DataGridView. So what I need to do is get the names from the interest table that are like what is put into text boxes then use those results to pull the data from the CaseSelector table and set the bindingsource filter to those results. Why can't I seem to set results to the caseSelectorBindingSourceFilter
var results = from CaseSelector in db.CaseSelectors
from Interest in db.Interests
where SqlMethods.Like(Interest.First, txtFirst.Text) && SqlMethods.Like(Interest.Last, txtLast.Text)
select CaseSelector;
caseSelectorBindingSource.Filter = ("CaseNumberKey =" + results);
You can find examples for LINQ join queries here:
http://code.msdn.microsoft.com/101-LINQ-Samples-3fb9811b
I don't know your DB schema but you're looking for something along the lines of:
from c in db.Cases
join i in db.Interest on i.CaseNumberKey equals c.CaseNumberKey
select c
What you've just retrieved is a SQL Set of the valid caseNumberKeys.
Your casefilter should be something like
caseSelectorBindingSource.Filter = "CaseNumberKey in " + interestsresultsAsSQLSET;
You'll have to iterate over the interestsresults and convert it to the string representation of a SQLSET. If you're feeling lucky, you could just try to .toString() it and see what happens.
string interestsResultsAsSQLSet = "(";
//write most of them
for(int i=0; i<interestsresults.size() - 1; i++) {
interestsResultAsSQLSet.append(interestsresults[i] + ",");
//write the last one, with right paren
interestsresults.append(interestsresults[interestsresults.size() -1] + ")");
I write Java all day, ignore my basic language errors. :P

Can LINQ To SQL detect where a table association breaks?

I have two tables I am using to fill a gridview. The tables have a common field named RangeActivityID. My problem is that the database is very old and some of the older entries do not match up IDs between tables, so I am unable to add an association between them in the database.
I do not care about the old data which doesn't match up, so in my .dbml file, I manually created an association in order to select good data from both tables. This is the LINQ query I have:
var collective = from p in rangeConnection.RangeActivities
orderby p.RangeActivityID
select new
{
TestName = p.TestName,
DateTime = p.ActivityDateTime,
Notes = p.Notes,
//RoundSerialNumber = p.RoundFire.RoundSerialNumber,
//RoundType = p.RoundFire.RoundType,
//LotStockNumber = p.RoundFire.LotNumber
};
I can set my grid datasource to 'collective' and everything works, but if I uncomment the three commented lines, the query returns no results because the tables have data that doesn't meet the association criteria. Is there a way to have the LINQ query ignore results that do not match up?
Thanks in advance!
Try to add where p.RoundFire != null criteria.
Suggest a join instead, and emulating a SQL LEFT JOIN.
var q = from p in rangeConnection.RangeActivities
join r in rangeConnection.RoundFires
on p.RangeActivityID equals r.RangeActivityID into sr
from x in sr.DefaultIfEmpty()
select new
{
TestName = p.TestName,
DateTime = p.ActivityDateTime,
Notes = p.Notes,
RoundSerialNumber = x.RoundSerialNumber,
RoundType = x.RoundType,
LotStockNumber = x.LotNumber
//consider checking for string.IsNullOrEmpty()
//for the RoundFires properties
};
The syntax for your entities may be inaccurate, but please edit my answer if it helps lead you to a solution.

Categories

Resources