I have the script:
select
fk.name,
object_name(fk.parent_object_id) 'Parent table',
c1.name 'Parent column',
object_name(fk.referenced_object_id) 'Referenced table',
c2.name 'Referenced column'
from
sys.foreign_keys fk
inner join
sys.foreign_key_columns fkc ON fk.object_id = fkc.constraint_object_id
inner join
sys.columns c1 ON fkc.parent_column_id = c1.column_id and c1.object_id = fkc.parent_object_id
inner join
sys.columns c2 ON fkc.referenced_column_id = c2.column_id and c2.object_id = fkc.referenced_object_id
And I know that I get a result set back with 5 columns. Is there is a slick and efficient way to store this data in a linq type object or an iQueryable object? I want to be able to iterate through it...
There are a few ORMs that use IQueryable: Entity Framework, LINQ to SQL, NHibernate, Subsonic, etc. I recommend trying one out.
For a very lightweight ORM, you can use the DataContext's ExecuteQuery:
class YourRow
{
public string Col1 { get; set; }
public string Col2 { get; set; }
...
}
// DataContext takes a connection string as parameter
var db = new DataContext("Data Source=myServerAddress;" +
"Initial Catalog=myDataBase;User Id=myUsername;Password=myPassword;");
var rows = db.ExecuteQuery<YourRow>(#"
select fk.name,
object_name(fk.parent_object_id) 'Parent table',
...
");
If you can store your SQL query in a view, you can drag the view to a DBML file to have LINQ create the wrapper class for you.
If you execute this script by using a DbCommand and a DataReader you can iterate over the rows that are returned and add them to a list of a custom object that will hold the 5 columns.
You can then use Linq To Objects to filter the list even more.
Or you can use an ORM to map your entities to the database. If you create a Database View for your query you can map an entity to the view with for example the Entity Framework and use that to execute further queries.
You can store this into DataTable. You have add assembly System.Data.Exetensions in your project to used DataTable as IQueryable.
from tbl in dataTable.AsEnumerable()
//where clause
select tbl;
DataView view = tbl.AsDataView();
Related
There may be similar questions out here but none that I could find for doing a subSelect in the FROM clause as a virtual table.
Most of the columns I need are in one table. There are a few columns needed from different tables that I cannot join on without getting a Cartesian join.
Here is my SQL query:
SELECT meter_name, a.loc_id, a.loc_name, a.facility_name, meter_type
FROM meter_table, (SELECT loc_id, loc_name, facility_name
FROM facility_table
WHERE id = 101) a
WHERE meter_id = a.fac_id
I have no idea how to convert this into Linq and it must be done tonight for a demo in the morning.
Assume this represents your meter_table within your database
in this case each element of the list represents a record in the database table holding the appropriate attributes
i.e the table columns will become the properties of each object
List<Meter> meter_table = new List<Meter>();
Assume this represents the facility_table table you want to join with.
same goes here, each element of the list represents a record in the database table holding the appropriate attributes
i.e the table columns will become the properties of each object
List<Facility> facility_table = new List<Facility>();
then perform the inner join like so:
var query = from m in meter_table
join a in facility_table on m.meter_id equals a.fac_id
where a.id == 101
select new { meter_name = m.MeterName,
loc_id = a.LocId,
facility_name = a.FacilityName,
meter_type = m.MeterType
};
where m.MeterName, a.LocId, a.FacilityName, m.MeterType are properties of their respective types.
it's also worth noting the variable query references an IEnumerable of anonymous types. However, if you want to return an IEnumerable of strongly typed objects then feel free to define your own type with the appropriate properties then just change select new to:
select new typeName { /* assign values appropriately */}
of the above query.
I have the following tables in my database:
SageAccount
ID (bigint)
LegacyID (nvarchar)
Customer (bit)
Consignments
ID (bigint)
Customer (nvarchar)
What I want to do is have a navigation property/association in my Linq to Sql dbml from Consignment to SageAccount. The difficulty with this is that not only do we need to match SageAccount.LegacyID => Consignments.Customer but we also need to only join to sage accounts where SageAccount.Customer is TRUE. So on the Consignments end, it isn't joining onto a field but instead a static value.
Is this possible in Linq to Sql? Note this database doesn't (and unfortunately can't) have any foreign keys setup in the database.
Yes it is possible. linq have join method. You can use it ike this in your situation:
var res = from sageAccount in _context.SageAccount
join consignments in _context.Consignments
on
new
{
LegacyID = sageAccount.LegacyID,
Customer = sageAccount.Customer
}
equals
new
{
LegacyID = consignments.ID,
Customer = true
}
select new { SageAccountID = sageAccount.ID };
Note that Property name, Type and order in the anonymous objects that you're joining on must match.
You can't use OR and AND in joins - use just equals one object to other.
This will have a this kind of result in your SQL:
SELECT [t0].[ID] AS [SageAccountID]
FROM [dbo].[SageAccount] AS [t0]
INNER JOIN [dbo].[Consignments] AS [t1] ON (([t0].[LegacyID]) = [t1].[ID])
AND ([t0].[Customer] = 1)
Try to do a single database call to get an entity, as well as the count of related child entities.
I know I can retrieve the count using
var count = Context.MyChildEntitySet.Where(....).Count();
or even MyEntity.ListNavigationProperty.Count()
But That means getting the entity first, followed by another call in order to get the count or use an Include which would retrieve the whole list of related entities.
I am wondering is it possible to add a "Computed" column in SQL Server to return the Count of related rows in another table?
If not how do I ask EF to retrieve the related count for each entity in once call?
I am thinking of possibly using Join with GroupBy, but this seems an Ugly solution/hack.
public class MyEntity
{
public uint NumberOfVotes{ get; private set; }
}
which ideally woudl generate SQL Similar to:
SELECT
*,
(SELECT Count(*) FROM ChildTable c WHERE c.ParentId = p.Id) NumberOfVotes
FROM ParentTable p
UPDATED
You can always drop down to using actual SQL in the following way...
string query = "SELECT *,
(SELECT Count(*) FROM ChildTable c
WHERE c.ParentId = p.Id) as NumberOfVotes
FROM ParentTable p";
RowShape[] rows = ctx.Database.SqlQuery<RowShape>(query, new object[] { }).ToArray();
I realize this is not ideal because then you are taking a dependency on the SQL dialect of your target database. If you moved form SQL Server to something else then you would need to check and maybe modify your string.
The RowShape class is defined with the properties that match the ParentTable along with an extra property called NumberOfVotes that has the calculated count.
Still, a possible workaround.
I am new to entity framework. Here is my simple problem.
I have a SQL database mapped automatically to ADO .NET Entity Data Mode, I wrote a function
public List<table1> GetTable1()
{
return ( from t in context.table1 select t).ToList();
}
and then I attach the data:
List<table> list1 = GetTable1();
GridView1.DataSource = list1;
but when I wanted to use joined table1 and table2 in select statement I don't know what type of List to use.
What type should the function return so I could attach it to my GridView?
My only solution now is to create view on database joining those 2 tables and then update the entity Model, but this might be not very elegant way.
Thanks for help :)
This is quite similar to this question: How to get 2 different values in 2 different tables using c# linq
You need to create a new class that can encapsulate the result you want back. That way, you can return the type from your data access layer.
Use Anonimous Type inside the method where datasource is bound :
var list1 = (from t in context.table1 select new { ColumnFromTable1 = "whatever", FromOtherTable = "other" }).ToList();
GridView1.DataSource = list1;
Of course, you need to know how to join tables, the key point here is:
new { ColumnFromTable1 = "whatever", FromOtherTable = "other" }
I need to combine two or more table into one object by using C# 4,0... I wrote a class for a table which included simple select selectbyid insert update and update.... it works fine for single table... by the way I have two attribute which specifies table name column name and primarykey... by using all these I can create my simple methods but I need to select and update more table in one object or method... what should I do or what would you suggest about it...
Example:
users and customer table I have foreign keys which defined...
If you`re using linq to sql, you can join the other tables like
var q =
from s in db.Suppliers
join c in db.Customers on s.City equals c.City
select new {
Supplier = s.CompanyName,
Customer = c.CompanyName,
City = c.City
};
as just copy & paste from a sample of MSDN LINQ to SQL: .NET Language-Integrated Query for Relational Data