Linq how to move all values of two columns to another table - c#

I want to move 2 columns of my table to an another table. I can select values that i want to move but i'am unable to move them. How can i make this ? Here is my implementation
var cartQuery = (from c in db.CartTbls.AsQueryable()
join cs in db.CartShoeTbls on c.CartID equals cs.CartID
where c.CustomerID == cusID
select new {c.CustomerID,c.TotalPrice,cs.ShoeID,cs.Quantity});
What i want to do is copy the all values of ShoeID and Quantity attiributes. Any help would be appriciated.

Use should add the selection to the table and save the changes:
foreach (var item in cartQuery)
db.OrderShoeTbl.Add(new OrderShoe()
{ ShoeID = item.ShoeID, Quantity = item.Quantity });
db.SaveChanges();
if you are using Linq to SQL, the insert is different and should look like this:
foreach (var item in cartQuery)
db.OrderShoeTbl.InsertOnSubmit(new OrderShoe()
{ ShoeID = item.ShoeID, Quantity = item.Quantity });
db.SubmitChanges();

Stefan's answer is OK however you may insert everything in one step:
var cartQuery = (from c in db.CartTbls.AsQueryable()
join cs in db.CartShoeTbls on c.CartID equals cs.CartID
where c.CustomerID == cusID
select new OrderShoeTbl{ShoeID = c.ShoeID, Quantity = c.Quantity});
db.OrderShoeTbl.InsertAllOnSubmit(cartQuery);
db.SubmitChanges();
EDIT
If you want to delete data from source table I would also wrap everything in single transaction to avoid inconsistency in case of errors.

Related

C# SqlCommandBuilder , CommandUpdate - how to write correct update based on select with outer join tables

I want is to update 2 fields: p.FlagaWaznosci and p.Notatka
My select looks like:
Select DISTINCT p.id,p.Model_Number,p.Product_Name,p.Website_Link,p.Entry_date,p.LastUpdate_date,p.PrzydzialRozmiarow_ID,p.FlagaWaznosci,p.Notatka,pr.NazwaRozmiarowki,wd.LINK_StockX
from Products p with(nolock)
left outer join Widok_Model_Sklep_Stockx_Linki wd with(nolock) on wd.Product_ID = p.id
left outer join PrzydzialRozmiarow pr with(nolock) on pr.id = p.PrzydzialRozmiarow_ID
inner join Shops s with(nolock) on s.ID = p.Shop_ID
There is just outer joins to get correct data that I need to be displayed in gridview. And now when values p.FlagaWaznosci or p.Notatka is changed I want to save update in my database.
I try to use
//loads dataand fill to gridview
DataTable WszystkieProduktyDlaDanegoSklepu;
SqlDataAdapter sda555123 = new SqlDataAdapter("here is my select", conn123);
sda555123.Fill(WszystkieProduktyDlaDanegoSklepu);
//later update table Prooducts and save changed on p.Notatka and p.FlagaWaznosci
cmdbl = new SqlCommandBuilder(sda555123);
cmdbl.ConflictOption = ConflictOption.OverwriteChanges;
sda555123.Update(WszystkieProduktyDlaDanegoSklepu);
But this way I have error
So I searched a lot and found: I have to write own CommandUpdate.
So ... sda555123.UpdateCommand and I don't have idea how can I write own update for it in update command.
The update in SQL Server should looks like:
Update Products
set FlagaWaznosci = #Flagawaznosci from my sda555123,
Notatka = #Notatka from my sda555123
where id = # p.ID from my sda555123
How my command update should looks like here?
EDIT 1 :
i try added : WszystkieProduktyDlaDanegoSklepu.PrimaryKey = new DataColumn[] { WszystkieProduktyDlaDanegoSklepu.Columns["id"] }
but nothing . Still this error.
I would solve the problem by changing the approach instead of mutating the update command of the SqlDataAdapter.
Given that Products.id in your query is unique within the result set:
1- Create a temporary table (local or global), having its columns same as the result of the query with id as primary key.
2- Insert data into the temporary table using your select statement.
3- DataAdatper.selectQuery.commandText is set to "select * from TempTable"
4- The update command is now based on a simple select statement, consequently any change in the datagridview/datatable can be updated to the temptable using dataadapter.update(datatable)
5- As for the final database update, you could use the below statement
Update Prd
set Prd.FlagaWaznosci = TempTable.FlagaWaznosci ,Prd.Notatka = TempTable.Notatka etc.. all the fields that need to be updated
from my Products as Prd
Inner Join TempTable on TempTable.id = Prd.id
Note that the update in (5) will affect all rows, even unchanged ones.
To address this issue you can proceed as below
1- Save changed ids in a list.
List<string> lst = new List<string>();
foreach(DataRow dr in datatable.GetChanges(DataRowState.Modified))
{
lst.add(dr["id"].ToString());
}
2- Convert your list to a string value to be concatenated with the query in (5)
String strchange = String.Join(",",lst); //will give you id1,id2,...
//The update query becomes
Update Prd
set Prd.FlagaWaznosci = TempTable.FlagaWaznosci ,Prd.Notatka =
TempTable.Notatka etc.. all the fields that need to be updated
from my Products as Prd
Inner Join TempTable on TempTable.id = Prd.id
Where Prd.id In ( strchange )
Kindly update your tables separately because in join you just seen two or more than two tables into one table form . but you cant do any crud operation on

Select ID from Table where it does not match ID in another table

The title says most of what I wish to do. I have two tables "orders" and "Customers". the orders table contains the customerID of every customer who has placed an order and the customers table contains every customerID. I need to select and display the customers who have not placed an order. I know
I need to display the rows where the customerID from the customers table does not match the customerID from orders table.
I am not sure how to do this however and have not come across a solution that I can understand so any help would be much appreciated. This is what I have tried doing.
private void btnQ9_Click(object sender, RoutedEventArgs e)
{
DataClasses1DataContext dc = new DataClasses1DataContext();
var query = from c in dc.Customers
join o in dc.Orders on c.CustomerID equals o.CustomerID
group o by new { o.CustomerID, c.CompanyName } into grp
where(grp.Key.CustomerID.Count() ==0)
select new
{
CompanyName = grp.Key.CompanyName,
Order = grp.Key.CustomerID.Count()
};
DataQ9.ItemsSource = query.ToList();
}
It seems like you just want
from c in dc.Customers
where !dc.Orders
.Select(o => o.CustomerID)
.Contains(c.CustomerID)
or
from c in dc.Customers
where !dc.Orders
.Any(o => o.CustomerID == c.CustomerID)
They might generate different SQL so I would try both and see which one performs better (if the difference is even noticeable).

C# Linq to Entity Framework multiple unrelated queries

I have a situation where I need data from multiple database tables.
Table 1 - has list of columns which needs to be displayed on front end html, angular kendo grid - which is configurable from separate Admin configuration.
Table 2 (joining of some other tables)- has the data which needs to be displayed on the angular front end.
My linq here which I am using currently is as below.
Query 1: to get list of columns to be displayed on Grid
var columns = from cols in _context.columns
select cols.colNames;
Query 2: Get the actual data for list
var data = from cust in _context.customer
join details in _context.custDetails on cust.id equals details.custid
join o in _context.orders on cust.id equals o.custid
where cust.id == XXXX
select new Customer
{
Id = cust.Id,
Name = cust.Name,
Address = details.Address,
City = details.City,
State = details.State,
OrderDate = o.OrderDate,
Amount = o.Amount
//15 other properties similarly
};
returns IQueryable type to Kendo DataSourceRequest
Currently, From my ui I have been make two api calls one for columns and one for getting the actual data, and show/hide the columns which are configured in the columns table.
But the problem is if anyone looks at the api calls on the network or on browser tools they could see the data being returned for the columns that are to be hidden which is a security problem.
I am looking for a single query for my api which returns the data using second query which should be smart enough to send the data only for configured columns (there could be 30 different columns) and set the other properties to null or doesn't select them at all. there are some properties which needs to be returned always as they are being used for some other purpose.
I searched many resources on how could I generate dynamic linq select using the configured columns.
Please some one help me in resolving this problem
you can do something like this. Assuming you columns tables a Boolean column Display and when it is true Column will be displayed and when it is false it wont be displayed.
var columns = (from cols in _context.columns
select cols).ToList(); // note I am getting everything not just column names here...
var data = from cust in _context.customer
join details in _context.custDetails on cust.id equals details.custid
join o in _context.orders on cust.id equals o.custid
where cust.id == XXXX
select new Customer
{
Id = cust.Id,
Name = cust.Name,
Address = details.Address,
City = details.City,
State = details.State,
OrderDate = o.OrderDate,
Amount = o.Amount
//15 other properties similarly
}.ToList();
var fileterdData = from d in data
select new Customer
{
Id = DisplayColumn("ID",columns)? cust.Id:null,
Name = DisplayColumn("Name",columns)? cust.Name:null,
Address = DisplayColumn("Address",columns)? details.Address:null,
// do similarly for all other columns
}.AsQueryable(); // returns IQueryable<Customer>
private bool DisplayColumnn(string columnName,List<Columns> cols)
{
return cols.Where(x=>x.ColumnName==columnName).First().Display();
}
So now you will have this code as part of one web API call which is going to do two SQL calls one to get columns and other to get data then you will use Linq To Entity filter columns which you dont want ( or want them to null). return this filtered data back to UI.

Issue with combobox when I bind using linq join query

I am binding ComboBox using LINQ Join query. Below is my code:
var list = (from a in context.tbl_Products
join c in context.tbl_CurrentStock on a.ProductID equals c.ProductID
where c.Qty > 0
select new
{
ProductID = a.ProductID,
ProductName = a.ProductName
}).ToList();
cmbProduct.DataSource = list;
cmbProduct.ValueMember = "ProductID";
cmbProduct.DisplayMember = "ProductName";
cmbProduct.SelectedIndex = -1;
Table Details:
tbl_Products : ProductID, Product Name
Data in table
1,ABC
2,BCA
3,CDA
tbl_CurrentStock: StockID,ProductID,Qty
Data in table:
1,1,5
2,2,10
3,3,50
I am using cmbProduct.SelectedValue like below:
int ProductID = Convert.ToInt32(cmbProduct.SelectedValue);
var Product = context.tbl_Products.Single(o => o.ProductID == ProductID);
Until here it is fine. In combobox I have selected "ABC", but I am getting cmbProduct.selectedvalue value as 2 instead of 1. Same way if I select 2nd product getting value as 3 instead of 2, it is not giving selected value, instead it is giving first value in the list. What could be the problem? It's silly and eating my head. This is working fine, when I don't use JOIN Query (if I bind data from only one table)
Thanks in Advance
Problem resolved after changing sorted property of combobox to false. Combobox is sorting the productnames but not product IDs. This was causing issue. –

asp.net Ado stored procedure fields

I have the following select in an stored procedure:
Select I.ID,
I.Name,
I.NameUrl,
I.Teaser,
I.Description,
I.Coords,
I.Banned,
I.DateAdded,
I.TypeID,
I.MainCategoryID,
C.Name,
C.NameUrl,
C.Description
from Items I
inner join Categories C on C.ID=I.MainCategoryID
Some of the columns in few tables have the same name.
The asp.net ADO code below doesnt work for this equal names that im using.
My question is: Do i have to give a name, in the sql query, to the fields C.Name, C.NameUrl and C.Description in order to get it from the datatable indicated below? I Mean, i would like to avoid to put (in every stored procedure) the "C.Name as CategoryName", "C.ID as CategoryID", etc... Do you know a solution?
item.Name = Convert.ToString(dt.Rows[0]["Name"]);
item.NameUrl = Convert.ToString(dt.Rows[0]["NameUrl"]);
item.Teaser = Convert.ToString(dt.Rows[0]["Teaser"]);
item.Description = Convert.ToString(dt.Rows[0]["Description"]);
item.DateAdded = Convert.ToDateTime(dt.Rows[0]["DateAdded"]);
item.IsBanned = Convert.ToBoolean(dt.Rows[0]["Banned"]);
item.MainCategory = new Category();
item.MainCategory.ID = Convert.ToInt32(dt.Rows[0]["MainCategoryID"]);
item.MainCategory.Name = Convert.ToString(dt.Rows[0]["C.Name"]);
item.MainCategory.NameUrl= Convert.ToString(dt.Rows[0]["C.NameUrl"]);
Thanks in advance.
Regards.
Jose
You can use the column name from the result set without the qualifier.
However, you have ambiguous column names. So you need to alias them:
Select I.ID,
I.Name AS ItemName,
I.NameUrl AS ItemNameUrl,
I.Teaser,
I.Description AS ItemNDescription,
I.Coords,
I.Banned,
I.DateAdded,
I.TypeID,
I.MainCategoryID,
C.Name AS CategoryName,
C.NameUrl AS CategoryNameUrl,
C.Description AS CategoryDescription
from Items I
inner join Categories C on C.ID=I.MainCategoryID
and
item.Name = Convert.ToString(dt.Rows[0]["ItemName"]);
item.NameUrl = Convert.ToString(dt.Rows[0]["ItemNameUrl"]);
item.Teaser = Convert.ToString(dt.Rows[0]["Teaser"]);
item.Description = Convert.ToString(dt.Rows[0]["ItemDescription"]);
item.DateAdded = Convert.ToDateTime(dt.Rows[0]["DateAdded"]);
item.IsBanned = Convert.ToBoolean(dt.Rows[0]["Banned"]);
item.MainCategory = new Category();
item.MainCategory.ID = Convert.ToInt32(dt.Rows[0]["MainCategoryID"]);
item.MainCategory.Name = Convert.ToString(dt.Rows[0]["C.CategoryName"]);
item.MainCategory.NameUrl= Convert.ToString(dt.Rows[0]["C.CategoryNameUrl"]);
item.MainCategory.Description= Convert.ToString(dt.Rows[0]["C.CategoryDescription"]);
...
The solution would be to refactor your database to use the right column names. Without refactoring your database, you will have to refactor your stored procedures to correctly identify the columns.
Either way, you are in for quite a bit of typing.
It will be better if you do aliasing, otherwise it will always give problem
Select I.ID,
I.Name as IName,
I.NameUrl,
I.Teaser,
I.Description as Idescription,
I.Coords,
I.Banned,
I.DateAdded,
I.TypeID,
I.MainCategoryID,
C.Name as CName,
C.NameUrl,
C.Description as Cdescription from Items I
inner join Categories C on C.ID=I.MainCategoryID
Probably use an alias for the same naming column like
Select I.ID,
I.Name as itemname,
I.NameUrl as itemurl,
I.Teaser,
I.Description as itemdesc,
I.Coords,
I.Banned,
I.DateAdded,
I.TypeID,
I.MainCategoryID,
C.Name as catname,
C.NameUrl as caturl,
C.Description as catdesc
from Items I inner join Categories C on C.ID=I.MainCategoryI
As a few others have said, you'll need to alias the names in your Stored Procedure and they have given you examples on how to do so. Alternatively, you can SELECT INTO a temp table and name them what you would like and then have your code pull from the temp table without any aliasing needed on the code-side. However, there is no getting around having to alias the stored procedure. Good Luck!

Categories

Resources