I am trying to make a generic function to do a database call (see code below). I have put the function in a separate solution, so that i can use it in different projects.
the line:
var data = d.Database.SqlQuery<T> (sql).First();
gives me the error:
Invalid object name 'VM_MailData'
(VM_MailData is the type I add as generic type T)
public static void ProcessData<T>(string Group, int Id)
{
string ConnectionString = "SomeConnectionStringName";
string sql = "select top 1 * from " + (typeof (T).Name) + " where " + Group + "Id = " + Id + ";";
DbContext d = new DbContext(ConnectionString);
var data = d.Database.SqlQuery<T> (sql).First();
//Do some stuff with the data...
html = "some tekst...";
foreach (var sourceProperty in data.GetType().GetProperties())
{
html = html.Replace("{#" + sourceProperty.Name + "#}", sourceProperty.GetValue(data, new object[] { }) == null ? "" : sourceProperty.GetValue(data, new object[] { }).ToString());
//enter code here
}
}
You most probably need to call ProcessData<T>(string Group, int Id) with some base type of VM_MailData. I assume that VM stands for "view model" and you have something like
public class MailData
{
}
public class VM_MailData : MailData
{
}
Where MailData class is actually the one that has a corresponding table.
So instead of calling ProcessData<VM_MailData >("some group", 1) you need to call ProcessData<MailData>("some group", 1).
P.S. You really should use parameterized queries to avoid SQL Injection!
I can see where you're heading :) so...
You have to create a map (dictionary) that maps from Type to appropriate table name. You can built that using some kind of convention based on the name of the type or the tables.
Use those to get available tables and views in the dabatase
SELECT SCHEMA_NAME(schema_id) as SchemaName, name as Name FROM sys.tables
SELECT SCHEMA_NAME(schema_id) as SchemaName, name as Name FROM sys.views
You can use the following script to get the primary key column of the table.
DECLARE #origin_table_name AS VARCHAR(50)
SET #origin_table_name = 'Your_table_name_goes_here'
SELECT
s.name AS TABLE_SCHEMA
, t.name AS TABLE_NAME
, c.name AS COLUMN_NAME
, k.name AS CONSTRAINT_NAME
, ic.key_ordinal AS ORDINAL_POSITION
FROM
sys.key_constraints AS k
JOIN sys.tables AS t ON t.object_id = k.parent_object_id
JOIN sys.schemas AS s ON s.schema_id = t.schema_id
JOIN sys.index_columns AS ic ON ic.object_id = t.object_id
AND ic.index_id = k.unique_index_id
JOIN sys.columns AS c ON c.object_id = t.object_id
AND c.column_id = ic.column_id
WHERE
k.type = 'PK'
AND t.name = #origin_table_name
Good luck
Related
var db = new SQLiteConnection(dbPath);
try
{
var results = db.Query<Xclass>("SELECT X.COL1, X.COL2, " +
" X.COL3, X.Col4, X.Col5, " +
" A.Col2, A.COL3, B.Col2, C.Col2 " +
"FROM left join Xam X " +
"left join TABLE1 A on X.COL1 = A.COL1 " +
"left join TABLE2 B on X.COL2 = B.COL1 " +
"left join TABLE3 C on X.COL3 = C.COL1 " +
"WHERE X.COL1 ='"+ somevalue +"'");
}
catch (Exception e)
{
// display message
}
XCLASS Contains all the getters and setters.
But it only pulls in the Xam table and not the A, B, or C table values.
I originally had the table name in the Class but took it out to see if that would help.
Any assistance is appreciated. I am trying to avoid linq but if is necessary I will try it.
The instance(s) of Xclass object is created from the results of your query via reflection.
The columns in query's result set are translated to properties of the class
and the setters of hese properties are used to assign their values.
Therefore you must supply some hints to SQlite so it will know which column corresponds to which property. This is done via as keyword.
So, if you want assign the value of A.COL2 column in the result to property named MyCol2Property inside Xclass, you must retrieve it in the query using the syntax
A.Col2 as MyCol2Property
I want to build a dynamic script component as source and destionation for multible tables. I just started by sample at Microsoft Page. It is working for specific table but now need to convert it to dynamic for all tables but need your helps.
First I thought to generate 'MyAddressOutputBuffer.Column' part dynamicly by below sql query.
SqlCommand cmdMeta = new SqlCommand(#"
select ColumnMapping = ' MyAddressOutputBuffer.Column'+cast(RANK() OVER(ORDER BY c.name)-1 as varchar(5))+' = sqlReader.GetValue(' + cast(RANK() OVER(ORDER BY c.name) - 1 as varchar(5)) + ').ToString();'
from sys.tables t
inner join sys.columns c on t.object_id = c.object_id
where t.name = 'Address'", sqlConn);
sqlReaderMeta = cmdMeta.ExecuteReader();
Above code give expected result but not sure how replace with hardcoded mapping with below part :
public override void CreateNewOutputRows()
{
while (sqlReader.Read())
{
{
MyAddressOutputBuffer.AddRow();
MyAddressOutputBuffer.AddressID = sqlReader.GetValue(0).ToString(); // I use getVAlue for all data types.
MyAddressOutputBuffer.City = sqlReader.GetValue(1).ToString();
}
}
}
Is there any way to say C# to run dynamic query which return from above sql instead of hardcoded?
I am trying to combine two tables in c# for orderManagement.where "SalesOrderDetails" table returns query results 1 comma seperated product code and quantity
query results 2
"SalesOrder" table return order detail.
I have Written stored procedure
ALTER procedure [dbo].[SP_GetAllOrders]
AS
BEGIN
SELECT
SalesOrder.OrderDate,
SalesOrder.OrderTitle,
SalesOrder.OrderPriority,
Customer.Lname,
Customer.Fname,
OrderType.OrderTypeName,
(
SELECT
CAST( ProductCode AS varchar ) + ':' + CAST( Quantity AS varchar ) + ','
FROM
SalesOrderDetails
WHERE
SalesOrderDetails.SalesOrderId = SalesOrder.SalesOrderId
FOR xml path('')
) AS 'Product'
FROM
SalesOrder
INNER JOIN Customer ON SalesOrder.CustomerId = Customer.CustomerId
INNER JOIN OrderType ON SalesOrder.OrderTypeId = OrderType.OrderTypeId
END
It gives me perfect output.same output I want without using stored procedure.
I want same output using entity framework,linq and c# asp.net.I am stuck here
this is what i have tried
TrainingDemoEntities entity = new TrainingDemoEntities();
var details = (from order in entity.SalesOrders
join cust in entity.Customers
on order.CustomerId equals cust.CustomerId
join ordertypevalue in entity.OrderTypes
on order.OrderTypeId equals ordertypevalue.OrderTypeId
select new
{
orderId = order.SalesOrderId,
orderDate = order.OrderDate,
orderTitle = order.OrderTitle,
orderPriority = order.OrderPriority,
orderType = order.OrderType,
productstr = string.Join(",", (from prod in entity.SalesOrderDetails
where prod.SalesOrderId == order.SalesOrderId
select prod.ProductCode + ":" + prod.Quantity))
}).ToList();
I am trying to execute a raw query using c#.
Here is what I have done
var accounts = conn.Database.SqlQuery<IEnumerable<string>>("SELECT TOP 1 a.* FROM zipcodes_to_accounts AS c " +
"INNER JOIN accounts AS a ON a.id = c.account_id " +
"WHERE c.zip_code = #p0 "+
"ORDER BY a.completed_ll + a.completed_cp ASC", zipcode).ToArray();
Then I want to take the first record and convert it to json object.
if (accounts.Count() > 0)
{
return JsonConvert.SerializeObject( accounts.First() );
}
But the query is giving me an error
The result type 'System.Collections.Generic.IEnumerable`1[System.String]' may not be abstract and must include a default constructor.
The accounts table has some columns that are varchar, datetime, integers. How can I get this query to work?
UPDATED
Converting the IEnumerable to list like advised in the answer it working. but now the JsonConvert is returning an empty object. Here is my current code
//getAccount
public string GetAccount()
{
string zipcode = StringHelpers.StringOrNull(Request["zip_code"]);
if (zipcode != null)
{
var accounts = conn.Database.SqlQuery<List<string>>("SELECT TOP 1 a.* FROM zipcodes_to_accounts AS c " +
"INNER JOIN accounts AS a ON a.id = c.account_id "+
"WHERE c.zip_code = #p0 "+
"ORDER BY a.completed_ll + a.completed_cp ASC", zipcode).ToList();
var firstAccount = accounts.FirstOrDefault();
if (firstAccount != null)
{
return JsonConvert.SerializeObject(firstAccount);
}
}
return "{}";
}
When I debug my code Here is what I see
Not sure what ORM you're using, but the warning is telling you that IEnumerable cannot be constructed as it's an interface. Therefore the SqlQuery method can't know what return type you're expecting.
Try replacing the generic constraint with a concrete type:
var accounts = conn.Database.SqlQuery<string>("SELECT TOP 1 a.* FROM zipcodes_to_accounts AS c " +
"INNER JOIN accounts AS a ON a.id = c.account_id " +
"WHERE c.zip_code = #p0 "+
"ORDER BY a.completed_ll + a.completed_cp ASC", zipcode).ToArray();
You're asking for a IEnumerable<string> which is an interface. You need to pick a class that implements IEnumerable such as a List
I have following query,
var employees = from emp in this.DataWorkspace.v2oneboxData.me_employees
where emp.me_is_deleted.Value == false && emp.me_is_manager == true
select new{emp.me_first_name,emp.me_last_name,emp.me_pkey};
I want to give a specific name to emp.me_first_name column, just like we do in SQL Queries like:
select emp_first_Name as "First Name" from me_employees
how to do it in linq queries ???
also is it possible to combine firstName and lastname in select query in Linq ? just like we do in SQL Queries like :
select me_first_name + ' ' + me_last_name as 'Full Name' from me_employee
how can i achieve this task in linq?
Thanks
You can't make it First Name as that isn't a valid identifier, but you can use:
select new { FirstName = emp.me_first_name,
LastName = emp.me_last_name,
Key = emp.me_pkey };
Basically the property name in the anonymous type only defaults to whatever property you're using as the value - you can specify it yourself, but it has to be a valid C# identifier.
Or for the combination:
select new { FullName = emp.me_first_name + " " + emp.me_last_name,
Key = emp.me_pkey };
var list = fro e in emp
select new { FullName = e.Firstname + " " + e.LastName }
One of the example but its with the group by
Check more at : Learn SQL to LINQ (Visual Representation)
from emp in this.DataWorkspace.v2oneboxData.me_employees
where emp.me_is_deleted.Value == false && emp.me_is_manager == true
select new{FullName = String.Format("{0} {1}",emp.me_first_name, emp.me_last_name),emp.me_pkey};