Okay so I've already asked this question but I've narrowed it down and am now able to word it better.
I have a sql database and an asp.net mvc project with entity frameworks. I already figured out how to query the database and display all contents. But now I need to query the database and only display the rows where column "a" is greater than or equal to column "b".
Edit: datatypes in both columns are int
Here is the query I need
Select *
from Inventory
Where quantity <= statusLow
var context = new MyContext();
var query = context.Inventory.Where(p=> p.quantity <= p.statusLow); // write the statement to query
var result = query.ToList(); // obtaining the result, trigger the database
You can try as shown below.
using (var db = new yourContext())
{
var result = db.Inventory.Where(a=> a.quantity <= a.statusLow).ToList();
}
You can learn more about LINQ to Entities here.
Related
I using C# and LINQ to pull/push data housed in SQL Azure. The basic scenario is we have a Customer table that contains all customers (PK = CompanyID) and supporting tables like LaborTypes and Materials (FK CompanyID to Customer table).
When a new customer signs up, a new record is created in the Customers table. Once that is complete, I want to load a set of default materials and laborTypes from a separate table. It is simple enough if I just wanted to copy data direct from one table to another but in order to populate the existing tables for the new customer, I need to take the seed data (e.g. laborType, laborDescription), add the CompanyID for each row of seed data, then do the insert to the existing table.
What the best method to accomplish this using C# and LINQ with SQL Azure?
An example of a direct insert from user input for LaborTypes is below for contextual reference.
using (var context = GetContext(memCustomer))
{
var u = GetUserByUsername(context, memUser);
var l = (from lbr in context.LaborTypes
where lbr.LaborType1.ToLower() == laborType
&& lbr.Company == u.Company
select lbr).FirstOrDefault();
if (l == null)
{
l = new AccountDB.LaborType();
l.Company = u.Company;
l.Description = laborDescription;
l.LaborType1 = laborType;
l.FlatRate = flatRate;
l.HourlyRate = hourlyRate;
context.LaborTypes.InsertOnSubmit(l);
context.SubmitChanges();
}
result = true;
}
What you'll want to do is write a query retrieving data from table B and do an Insert Statement on Table A using the result(s).
This has been covered elsewhere in SO I think, here would be a good place to start
I don't know the syntax for Linq specifically; but by constructing something similar to #Murph 's answer beyond that link, I think this might work.
var fromB= from b in TableB
where ... ;//identify the row/data from table B
// you may need to make fromB populate from the DB here.
var toInsert = ...; //construct your object with the desired data
// do other necessary things here
TableA.InsertAllOnSubmit(toInsert);
dc.SubmitChanges(); // Submit your changes
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
I am new to Linq to Sql. I got a scenario. I have two tables. MasterTable and DetailTable table. What I am trying to do is :
Inserting new rows in the DetailTable and on base of DetailTable rows I am trying to Update Master in One transaction.
Here is my code :
DBContext context = new DBContext();
context.Connection.Open();
context.Transaction = context.Connection.BeginTransaction();
DetailTable detail = new DetailTable();
detail.Amount = 100;
var detailTable = context.GetTable<DetailTable>();
// pass in the object with insert on submit
// and then submit changes
detailTable.InsertOnSubmit(detail);
var result = (from Total in context.MasterTable
select Total).Sum();
decimal total = (decimal)result; // This total is not the latest.
// UpdateMaster.....
// ................
context.SubmitChanges();
context.Transaction.Commit();
Now the problem, I am facing is that I am not getting the latest Sum from MasterTable. Like after inserting new row of amount 100, say I should get 600 but I am getting 500 (Sum rows as if I have not inserted new row).
Please let me know if this is possible using Linq to Sql if it is then how or I am trying to achieve something which is not possible.
Try to put the context.SubmitChanges(); above the decimal total = (decimal)result;
The data in your datacontext is stale. Linq-2-sql will not apply pending updates before your submitchanges.
So what you need to do is either the following:
decimal total = (decimal)result + detail.amount
or you do indeed what Jan P. has suggested above. That will work too since you are managing the transaction yourself.
Additionally: why are you opening the connection yourself? There is no need to do so in this case.
I have two tables: contacts and contact_temps. The contact_temps table mirrors the contacts table. What I'm trying to do is simply pull records from the temp table and insert them into contacts. Afterwards I will remove those records from the contact_temps table.
The code below only migrates one record and doesn't delete anything from the temp table. How can I fix my issue? Thanks.
// migrate temp profile(s)...
var tempProfilesToMigrate = from ct in db.contact_temps
where ct.SessionKey == contact.Profile.SessionId
select new contact();
db.contacts.InsertAllOnSubmit(tempProfilesToMigrate);
db.SubmitChanges();
//...clear temp table records
var tempProfilesToDelete = from ct in db.contact_temps
where ct.SessionKey == contact.Profile.SessionId
select ct;
db.contact_temps.DeleteAllOnSubmit(tempProfilesToDelete);
db.SubmitChanges();
I wonder if your "Insert All on Submit" is causing the entities to become associated with db.contacts. Try this.
// migrate temp profile(s)...
var tempProfiles = from ct in db.contact_temps
where ct.SessionKey == contact.Profile.SessionId
select ct;
foreach (var c in tempProfiles)
{
Contact newC = new Contact();
newC.Name = c.Name;
// copy other values
db.contacts.InsertOnSubmit(newC);
}
// WAIT! do it at once in a single TX => avoid db.SubmitChanges() here.
db.contact_temps.DeleteAllOnSubmit(tempProfiles);
// Both sets of changes in one Tx.
db.SubmitChanges();
You can also write a stored-proc and import it into the db context and just call it.
var result = db.ExecuteCommand("insert into contacts select * from contacts_temp where SessionKey={0}",contact.Profile.SessionId);
Of course, that's just off the top of my head, but you get the idea. Even better would be to put the migration and deletion into a stored procedure. The method you're using will round trip all the contact_temp records twice (once back and forth for the insert, once for the delete).
P.S. google "code first stored procedures" for a way to call stored procs using EF 4.1
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.