Compare 2 lists and reduce quantities of resulting list - c#

I have 2 lists
grpoList
I have a second named assembly
I have the following code
grpoList = grpoList.Where(c => assembly.Exists(cr => cr.ItemCode == c.ItemCode)).ToList();
This returns
How do I amend the code such that the line of DocEntry 393 on the results has a quantity of 2 instead of 4?

You probably want to perform a Join between the list and select the required fields out of it like
var data = grpoList.Join(assembly,
x => x.ItemCode,
y => y.ItemNo,
(x, y) => new
{
DocEntry = x.DocEntry,
LineNum = x.LineNum,
CarCode = x.CarCode,
ItemCode = x.ItemCode,
OpenQty = y.OpenQty,
DocDate = x.DocDate
}).ToList();

we can use linq joins to create the custom outputs:
var query = from c in grpoList
join cr in assembly
on c.ItemCode equals cr.ItemCode
select new
{
c.DocEntry,
c.LineNum,
c.CarCode,
c.ItemCode,
OpenQty = c.OpenQty - cr.OpenQty,
c.DocDate
};
Keeping name c and cr same as your question so that you can understand it easily.

Related

convert rows to column in entity framwork

how can i convert rows to column in entity framework!?
i have a result like this:
and i want this result:
my entity code i this :
(from loanPerson in context.LoanPersons.AsParallel()
join warranter in context.Warranters.AsParallel() on loanPerson.Id equals warranter.LoanPersonId
where loanPerson.Id == 84829
select new
{
loanPersonId = loanPerson.Id,
waranterId = warranter.WarranterPersonID,
}).ToList();
and number of the row always less than 3 and i want to have 3 column.
please let me know your answer.
tanks.
This query will return the only one row, where waranterIds will contain, at this particular case, three WarranterPersonID values, also this field is of List<int> type, because it's quantity not known at compile time:
var answer = (from loanPerson in context.LoanPersons.Where(x => x.Id == 84829)
join warranter in context.Warranters
on loanPerson.Id equals warranter.LoanPersonId
group warranter by loanPerson.Id into sub
select new
{
loanPersonId = sub.Key,
waranterIds = sub.Select(x => x.LoanPersonId).ToList()
//if you sure, that quantity equals 3,
//you can write this code instead of waranterIds:
//zamen1 = sub.Select(x => x.LoanPersonId).First(),
//zamen2 = sub.Select(x => x.LoanPersonId).Skip(1).First(),
//zamen3 = sub.Select(x => x.LoanPersonId).Skip(2).First()
}).ToList();

How can generate a sequence number inside a LINQ select?

I am getting a hard time generating a sequence number for my list using Linq Select.
I tried to use a normal variable i then increment it inside but it's not working.
var grouped = (from x in jOMACDetails
group x by new { x.MAWorkCode, x.ConstructionNumber } into g
let f = g.First()
select new UtilityReceivingReportDetailEntity
{
DefaultAccountCode = string.IsNullOrWhiteSpace(f.AccountTitleCode) ? f.AccountTitleName.Trim() : f.AccountTitleCode.Trim(),
CompanyID = CurrentContext.CurrentCompanyID,
RRNumber = socnumber.Trim(),
RRSequenceNumber = (short)???, // <---- Here is the container the I need to be sequence
//...............
}).AsEnumerable();
can someone help me about this?
thanks in advance
You can try Select() overload which projects each element of a sequence into a new form by incorporating the element's index automatically:
var grouped = jOMACDetails.GroupBy(x => new { x.MAWorkCode, x.ConstructionNumber })
.Select(g => g.First())
.Select((r, index) => new UtilityReceivingReportDetailEntity
{
DefaultAccountCode = string.IsNullOrWhiteSpace(r.AccountTitleCode) ? r.AccountTitleName.Trim() : r.AccountTitleCode.Trim(),
CompanyID = CurrentContext.CurrentCompanyID,
RRNumber = socnumber.Trim(),
RRSequenceNumber = index
})
.AsEnumerable();
Sadly, there is not any query expression which uses that overload. So, I wrote my answer in method syntax. But, you can use .Select after finishing your query expression if you wish. But, IMHO there is no need.
You´re looking for this?
var i = 0;
var grouped = (from x in jOMACDetails
group x by new { x.MAWorkCode, x.ConstructionNumber } into g
let f = g.First()
select new UtilityReceivingReportDetailEntity
{
DefaultAccountCode = string.IsNullOrWhiteSpace(f.AccountTitleCode) ? f.AccountTitleName.Trim() : f.AccountTitleCode.Trim(),
CompanyID = CurrentContext.CurrentCompanyID,
RRNumber = socnumber.Trim(),
RRSequenceNumber = i++
}).AsEnumerable();

The LINQ expression contains references to queries that are associated with different contexts

Here's my code:
var myStrings = (from x in db1.MyStrings.Where(x => homeStrings.Contains(x.Content))
join y in db2.MyStaticStringTranslations on x.Id equals y.id
select new MyStringModel()
{
Id = x.Id,
Original = x.Content,
Translation = y.translation
}).ToList();
And I get the error that the specified LINQ expression contains references to queries that are associated with different contexts. I know that the problem is that I try to access tables from both db1 and db2, but how do I fix this?
MyStrings is a small table
Load filtered MyStrings in memory, then join with MyStaticStringTranslations using LINQ:
// Read the small table into memory, and make a dictionary from it.
// The last step will use this dictionary for joining.
var byId = db1.MyStrings
.Where(x => homeStrings.Contains(x.Content))
.ToDictionary(s => s.Id);
// Extract the keys. We will need them to filter the big table
var ids = byId.Keys.ToList();
// Bring in only the relevant records
var myStrings = db2.MyStaticStringTranslations
.Where(y => ids.Contains(y.id))
.AsEnumerable() // Make sure the joining is done in memory
.Select(y => new {
Id = y.id
// Use y.id to look up the content from the dictionary
, Original = byId[y.id].Content
, Translation = y.translation
});
You are right that db1 and db2 can't be used in the same Linq expression. x and y have to be joined in this process and not by a Linq provider. Try this:
var x = db1.MyStrings.Where(xx => homeStrings.Contains(xx.Content)).ToEnumerable();
var y = db2.MyStaticStringTranslations.ToEnumerable();
var myStrings = (from a in x
join b in y on x.Id equals y.id
select new MyStringModel()
{
Id = x.Id,
Original = x.Content,
Translation = y.translation
}).ToList();
Refer to this answer for more details: The specified LINQ expression contains references to queries that are associated with different contexts
dasblinkenlight's answer has a better overall approach than this. In this answer I'm trying to minimize the diff against your original code.
I also faced the same problem:
"The specified LINQ expression contains references to queries that are associated with different contexts."
This is because it's not able to connect to two context at a time so i find the solution as below.
Here in this example I want to list the lottery cards with the owner name but the Table having the owner name is in another Database.So I made two context DB1Context and DB2Context.and write the code as follows:
var query = from lc in db1.LotteryCardMaster
from om in db2.OwnerMaster
where lc.IsActive == 1
select new
{
lc.CashCardID,
lc.CashCardNO,
om.PersonnelName,
lc.Status
};
AB.LottryList = new List<LotteryCardMaster>();
foreach (var result in query)
{
AB.LottryList.Add(new LotteryCardMaster()
{
CashCardID = result.CashCardID,
CashCardNO = result.CashCardNO,
PersonnelName =result.PersonnelName,
Status = result.Status
});
}
but this gives me the above error so i found the other way to perform joining on two tables from diffrent database.and that way is as below.
var query = from lc in db1.LotteryCardMaster
where lc.IsActive == 1
select new
{
lc.CashCardID,
lc.CashCardNO,
om.PersonnelName,
lc.Status
};
AB.LottryList = new List<LotteryCardMaster>();
foreach (var result in query)
{
AB.LottryList.Add(new LotteryCardMaster()
{
CashCardID = result.CashCardID,
CashCardNO = result.CashCardNO,
PersonnelName =db2.OwnerMaster.FirstOrDefault(x=>x.OwnerID== result.OwnerID).OwnerName,
Status = result.Status
});
}

Linq to SQL joining two tables and populate GridView

I have two tables in my database, Building and Town. They look like this:
Building:
buildingid
buildingname
Town:
id
userid
buildingid
In Town there is one entry for each building a user has.
What i want is to populate a GridView for a user with a given userid. This GridView should include the buildingname and the number of buildings.
Building. I have tried this:
var buildings = (from Town in dc.Towns
join Building in dc.Buildings
on Town.buildingid equals Building.buildingid
select Building.buildingname);
gvBuildings.DataSource = buildings;
gvBuildings.DataBind();
But I don't know how to get the numbers for each building.
I have now been working on this for a while and a couple of your answers work. I have used this code:
var buildings = dc.Towns
.Where(t => t.userid == userid)
.GroupJoin(dc.Buildings,
t => t.buildingid,
b => b.buildingid,
(Town, Buildings) => new
{
BuildningName = Buildings.First().buildingname,
Count = Buildings.Count()
});
gvBuildings.DataSource = buildings.ToList();
gvBuildings.DataBind();
When i run this code my GridView ends up looking like this:
I need the buildings to be shown in groups, grouped by the buildingname. I have tried all of the suggestions but i cant get it to work.
Try grouping:
var buildings = dc.Towns
.Where(t => t.UserId == userId)
.GroupJoin(dc.Buildings,
t => t.BuildingId,
b => b.BuildingId,
(town, buildings) => new
{
BuildingName = buildings.First().BuildingName,
Count = buildings.Count
});
Keep in mind that when binding to a control you must supply a collection of type (or implementing) IList. This can be accomplished by calling ToList() on the buildings collection:
gvBuildings.DataSource = buildings.ToList();
gvBuildings.DataBind();
check linq differed execution
and than try the blow code might work for you
var buildings =
(from j in dc.Town
join i in dc.Buildings
on j.buildingId equals i.buildingId
where j.Userid = varUSerid
group new {i, j}
by new
{ i.BuildingID }
into
g
select new {
BuildingName = g.First<k=>k.BuildingName)
, count = g.Count() } ).ToList();
gvBuildings.DataSource = buildings;
gvBuildings.DataBind();
var buildings = (from Town in dc.Towns
join Building in dc.Buildings
on Town.buildingid equals Building.buildingid
into results
from r in results.DefaultIfEmpty()
group Town by new
{
r.BuildingId
} into groupedResults
where Town.UserID == parameteruserId
select new
{
BuildingName = Building.buildingname,
BuildingCount = groupedResults.Count()
});
Try this.. it should work.. i have a similar requirement..
manDbDataContext db = new DbDataContext();
var estimatedTotal = ( from est in db.AssignmentEstimatedMaterials
where est.assignment_id == Convert.ToInt32(Label_assignmentId.Text)
join materialdetail in db.Materials on est.material_id equals materialdetail.material_id
select new { est.qty,est.total_amount, materialdetail.material_name}).ToList();
GridView_estiamte_material.DataSource = estimatedTotal;
GridView_estiamte_material.DataBind();
Note, you should select individual data and it works.

Count occurrences of values across multiple columns

I am having a terrible time finding a solution to what I am sure is a simple problem.
I started an app with data in Lists of objects. It's pertinent objects used to look like this (very simplified):
class A {
int[] Nums;
}
and
List<A> myListOfA;
I wanted to count occurrences of values in the member array over all the List.
I found this solution somehow:
var results
from a in myListOfA
from n in a.Nums
group n by n into g
orderby g.Key
select new{ number = g.Key, Occurences = g.Count}
int NumberOfValues = results.Count();
That worked well and I was able to generate the histogram I wanted from the query.
Now I have converted to using an SQL database. The table I am using now looks like this:
MyTable {
int Value1;
int Value2;
int Value3;
int Value4;
int Value5;
int Value6;
}
I have a DataContext that maps to the DB.
I cannot figure out how to translate the previous LINQ statement to work with this. I have tried this:
MyDataContext myContext;
var results =
from d in myContext.MyTable
from n in new{ d.Value1, d.Value2, d.Value3, d.Value4, d.Value5, d.Value6 }
group n by n into g
orderby g.Key
select new { number = g.Key, Occurences = g.Count() };
I have tried some variations on the constructed array like adding .AsQueryable() at the end - something I saw somewhere else. I have tried using group to create the array of values but nothing works. I am a relative newbie when it come to database languages. I just cannot find any clue anywhere on the web. Maybe I am not asking the right question. Any help is appreciated.
I received help on a microsoft site. The problem is mixing LINQ to SQL with LINQ to Objects.
This is how the query should be stated:
var results =
from d in MyContext.MyTable.AsEnumerable()
from n in new[]{d.Value1, d.Value2, d.Value3, d.Value4, d.Value5, d.Value6}
group n by n into g
orderby g.Key
select new {number = g.Key, Occureneces = g.Count()};
Works like a charm.
If you wish to use LINQ to SQL, you could try this "hack" that I recently discovered. It isn't the prettiest most cleanest code, but at least you won't have to revert to using LINQ to Objects.
var query =
from d in MyContext.MyTable
let v1 = MyContext.MyTable.Where(dd => dd.ID == d.ID).Select(dd => dd.Value1)
let v2 = MyContext.MyTable.Where(dd => dd.ID == d.ID).Select(dd => dd.Value2)
// ...
let v6 = MyContext.MyTable.Where(dd => dd.ID == d.ID).Select(dd => dd.Value6)
from n in v1.Concat(v2).Concat(v3).Concat(v4).Concat(v5).Concat(v6)
group 1 by n into g
orderby g.Key
select new
{
number = g.Key,
Occureneces = g.Count(),
};
How about creating your int array on the fly?
var results =
from d in myContext.MyTable
from n in new int[] { d.Value1, d.Value2, d.Value3, d.Value4, d.Value5, d.Value6 }
group n by n into g
orderby g.Key
select new { number = g.Key, Occurences = g.Count() };
In a relational database, such as SQL Server, collections are represented as tables. So you should actually have two tables - Samples and Values. The Keys table would represent a single "A" object, while the Values table would represent each element in A.Nums, with a foreign key pointing to the one of the records in the Samples table. LINQ to SQL
's O/R mapper will then create a "Values" property for each Sample object, which contains a queryable collection of the attached Values. You would then use the following query:
var results =
from sample in myContext.Samples
from value in sample.Values
group value by value into values
orderby values.Key
select new { Value = values.Key, Frequency = values.Count() };

Categories