select from two list different - c#

i have two list list content listearticle and this the code of this list:
model = (
from article in db.Article
select new
{
ID = article.ID,
ARTICLE = article.CODEARTICLE,
PRIX= article.PRIX,
STOCK=article.STOCK,
IMAGE = article.Image,
DESCRIPTION= article.REFERENCE,
});
and another content list convention and this is the code :
var query = (
from article in db.convention
select new
{
ID = article.ID,
ARTICLE = article.CODEARTICLE,
PRIX = article.Prix,
});
i want to have a list listarticleconvention like this:
foreach (dynamic aa in model)
{
foreach (dynamic aa1 in list1)
{
if (aa.ARTICLE == aa1.ARTICLE)
{
aa.PRIXVHT = aa1.PRIXVHT;
}
}
}
Can someone help me to edit PRIXVHT when this article exist in list1 and thank you for your help
the error apperead is Additional information: Property or indexer '<>f__AnonymousType3.PRIXVHT' cannot be assigned to -- it is read only
i know that's just read read only but i need to edit it how can i do it
N.B/i have to use a form like that i mean something like foreach in this two list

You can join db.Article to db.convention and then select article.PRIX if query.PRIX is null.
from articleA in db.Article
join articleC in db.convention on articleC.ID equals articleA.ID into temp
from query in temp.DefaultIfEmpty()
select new
{
ID = articleA.ID,
ARTICLE = articleA.CODEARTICLE,
PRIX = (query== null ? articleA.PRIX : query.PRIX),
STOCK = articleA.STOCK,
IMAGE = articleA.Image,
DESCRIPTION = articleA.REFERENCE,
});

Related

Entity State Value cant be null

i have two tables orders and order detail and i have order foriegn key in order detail. and i am inserting ordertotal into order table and all other order info in order details but i am getting this error .please help me out and please tell me hw to use entity state to add values to foriegn key table.
and here is my saveorder controller function
[HttpPost]
public ActionResult SaveOrder(FormCollection fc)
{
ResturantContext context = new ResturantContext();
ShoppingCart myCart = (ShoppingCart)Session[WebUtil.CART];
User u = (User)Session[WebUtil.USER];
Order order = new Order();
order.TotalAmount = myCart.TotalAmount;
new OrderHandler().AddOrder(order);
foreach (var m in myCart.Items)
{
OrderDetails od = new OrderDetails();
od.ID = m.Id;
od.Price =m.Price;
od.Product_name = m.Name;
od.Quantity = m.Quantity;
od.Address = fc["Address"];
od.City = fc["City"];
od.DateOfOrder = DateTime.Now;
od.UserName = u.FullName;
od.Email = u.Email;
od.ContactNo = fc["ContactNo"];
od.Country = fc["Country"];
new OrderHandler().AddOrderDetails(od);
}
Session.Remove(WebUtil.CART);
return RedirectToAction("Index","Home");
}
od.Order will always be Null since you are not setting it anywhere in your code. Try at least set it like od.Order = order inside your loop before calling your OrderHandler().AddOrderDetails(od);

add two entry for every row - Linq C#

it is my query:
from customer in db.tblCustomers
select new
{
ID = customer.CustomerID,
Mobile = customer.Mobile1,
LastName = customer.Family
};
for every customer there is tow mobile phones, I need to add a new entry if the second mobile phone is not null. also I should change the LastName for second entry to something like "Second Mobile". How can I get two different entry from one customer using linq query?
Using the same generated type you can't have one with only one property of phone number and another with two. You can do:
from customer in db.tblCustomers
select new
{
ID = customer.CustomerID,
Mobile = customer.Mobile1,
SecondMobile = customer.Mobile2, // will be null if no second mobile exists
LastName = customer.Family
};
Otherwise what you can do is create a custom type Customer that will have a single phone number and a derived type ExtendedCustomer with two - and just instantiate the one or the other. Something along the psudo:
from customer in db.tblCustomers
select customer.Mobile2 != null ? new Customer(...) : new ExtendedCustomer(...);
If what you mean is having two different objects in the resulted collection then use union:
List<Customer> result = new List<Customer>();
foreach(var item in db.tblCustomers)
{
result.Add(new Customer(/*data for first mobile phone*/);
if(item.Mobile2 != null)
{
result.Add(new Customer(/*data for second mobile phone*/);
}
}
Could you please try this if it helps?
var customers = db.tblCustomers.SelectMany(x => x.GetMultipleRow()).ToList();
GetMultipleRow is an extension method as below.
public static class CustomerExtensions
{
public static IEnumerable<Customer> GetMultipleRow(this Customer cust)
{
yield return new Customer { CustomerID = cust.CustomerID, Mobile1 = cust.Mobile1, Family = cust.Family };
/* Data for first mobile*/
if (cust.Mobile2 != null)
yield return new Customer { CustomerID = cust.CustomerID, Mobile1 = cust.Mobile2, Family = cust.Family };
/* Data for second mobile*/
}
}

C# Linq get descendants on a subquery

I've been banging my head on the desktop for the past couple of hours trying to decipher this issue.
I'm trying to query an XML file with Linq, the xml has the following format:
<MRLGroups>
<MRLGroup>
<MarketID>6084</MarketID>
<MarketName>European Union</MarketName>
<ActiveIngredientID>28307</ActiveIngredientID>
<ActiveIngredientName>2,4-DB</ActiveIngredientName>
<IndexCommodityID>59916</IndexCommodityID>
<IndexCommodityName>Cucumber</IndexCommodityName>
<ScientificName>Cucumis sativus</ScientificName>
<MRLs>
<MRL>
<PublishedCommodityID>60625</PublishedCommodityID>
<PublishedCommodityName>Cucumbers</PublishedCommodityName>
<MRLTypeID>238</MRLTypeID>
<MRLTypeName>General</MRLTypeName>
<DeferredToMarketID>6084</DeferredToMarketID>
<DeferredToMarketName>European Union</DeferredToMarketName>
<UndefinedCommodityLinkInd>false</UndefinedCommodityLinkInd>
<MRLValueInPPM>0.0100</MRLValueInPPM>
<ResidueDefinition>2,4-DB</ResidueDefinition>
<AdditionalRegulationNotes>Comments.</AdditionalRegulationNotes>
<ExpiryDate xsi:nil="true" />
<PrimaryInd>true</PrimaryInd>
<ExemptInd>false</ExemptInd>
</MRL>
<MRL>
<PublishedCommodityID>60626</PublishedCommodityID>
<PublishedCommodityName>Gherkins</PublishedCommodityName>
<MRLTypeID>238</MRLTypeID>
<MRLTypeName>General</MRLTypeName>
<DeferredToMarketID>6084</DeferredToMarketID>
<DeferredToMarketName>European Union</DeferredToMarketName>
<UndefinedCommodityLinkInd>false</UndefinedCommodityLinkInd>
<MRLValueInPPM>0.0100</MRLValueInPPM>
<ResidueDefinition>2,4-DB</ResidueDefinition>
<AdditionalRegulationNotes>More Comments.</AdditionalRegulationNotes>
<ExpiryDate xsi:nil="true" />
<PrimaryInd>false</PrimaryInd>
<ExemptInd>false</ExemptInd>
</MRL>
</MRLs>
</MRLGroup>
So far i've created classes for the "MRLGroup" section of the file
var queryMarket = from market in doc.Descendants("MRLGroup")
select new xMarketID
{
MarketID = Convert.ToString(market.Element("MarketID").Value),
MarketName = Convert.ToString(market.Element("MarketName").Value)
};
List<xMarketID> markets = queryMarket.Distinct().ToList();
var queryIngredient = from ingredient in doc.Descendants("MRLGroup")
select new xActiveIngredients
{
ActiveIngredientID = Convert.ToString(ingredient.Element("ActiveIngredientID").Value),
ActiveIngredientName = Convert.ToString(ingredient.Element("ActiveIngredientName").Value)
};
List<xActiveIngredients> ingredientes = queryIngredient.Distinct().ToList();
var queryCommodities = from commodity in doc.Descendants("MRLGroup")
select new xCommodities {
IndexCommodityID = Convert.ToString(commodity.Element("IndexCommodityID").Value),
IndexCommodityName = Convert.ToString(commodity.Element("IndexCommodityName").Value),
ScientificName = Convert.ToString(commodity.Element("ScientificName").Value)
};
List<xCommodities> commodities = queryCommodities.Distinct().ToList();
After i got the "catalogues" I'm trying to query the document against the catalogues to achieve some sort of "groups", after all this, i'm going to send this data to the database, the issue here is that the xml files are around 600MB each and i get the everyday, so my approach is to create catalogues and just send the MRLs to the database joined to the "header" table that contains the Catalogues IDs, here's what i've done so far but failed miserably:
//markets
foreach (xMarketID market in markets) {
//ingredients
foreach (xActiveIngredients ingredient in ingredientes) {
//commodities
foreach (xCommodities commodity in commodities) {
var mrls = from m in doc.Descendants("MRLGroup")
where Convert.ToString(m.Element("MarketID").Value) == market.MarketID
&& Convert.ToString(m.Element("ActiveIngredientID").Value) == ingredient.ActiveIngredientID
&& Convert.ToString(m.Element("IndexCommodityID").Value) == commodity.IndexCommodityID
select new
{
ms = new List<xMRLIndividial>(from a in m.Element("MRLs").Descendants()
select new xMRLIndividial{
publishedCommodityID = string.IsNullOrEmpty(a.Element("PublishedCommodityID").Value) ? "" : a.Element("PublishedCommodityID").Value,
publishedCommodityName = a.Element("PublishedCommodityName").Value,
mrlTypeId = a.Element("MRLTypeID").Value,
mrlTypeName = a.Element("MRLTypeName").Value,
deferredToMarketId = a.Element("DeferredToMarketID").Value,
deferredToMarketName = a.Element("DeferredToMarketName").Value,
undefinedCommodityLinkId = a.Element("UndefinedCommodityLinkInd").Value,
mrlValueInPPM = a.Element("MRLValueInPPM").Value,
residueDefinition = a.Element("ResidueDefinition").Value,
additionalRegulationNotes = a.Element("AdditionalRegulationNotes").Value,
expiryDate = a.Element("ExpiryDate").Value,
primaryInd = a.Element("PrimaryInd").Value,
exemptInd = a.Element("ExemptInd").Value
})
};
foreach (var item in mrls)
{
Console.WriteLine(item.ToString());
}
}
}
}
If you notice i'm trying to get just the MRLs descendants but i got this error:
All i can reach on the "a" variable is the very first node of MRLs->MRL not all of them, what is going on?
If you guys could lend me a hand would be super!
Thanks in advance.
With this line...
from a in m.Element("MRLs").Descendants()
...will iterate through all sub-elements, including children of children. Hence your error, since your <PublishedCommodityID> element does not have a child element.
Unless you want to specifically return all child elements of all levels, always use the Element and Elements axis instead of Descendant and Descendants:
from a in m.Element("MRLs").Elements()
That should solve your problem.
However, your query is also difficult to read with the nested foreach loops and the multiple tests for the IDs. You can simplify it with a combination of LINQ and XPath:
var mrls =
from market in markets
from ingredient in ingredientes
from commodity in commodities
let xpath = $"/MRLGroups/MRLGroup[{market.MarketId}]" +
$"[ActiveIngredientID={ingredient.ActiveIngredientId}]" +
$"[IndexCommodityID={commodity.IndexCommodityID}]/MRLs/MRL"
select new {
ms =
(from a in doc.XPathSelectElements(xpath)
select new xMRLIndividial {
publishedCommodityID = string.IsNullOrEmpty(a.Element("PublishedCommodityID").Value) ? "" : a.Element("PublishedCommodityID").Value,
publishedCommodityName = a.Element("PublishedCommodityName").Value,
mrlTypeId = a.Element("MRLTypeID").Value,
mrlTypeName = a.Element("MRLTypeName").Value,
deferredToMarketId = a.Element("DeferredToMarketID").Value,
deferredToMarketName = a.Element("DeferredToMarketName").Value,
undefinedCommodityLinkId = a.Element("UndefinedCommodityLinkInd").Value,
mrlValueInPPM = a.Element("MRLValueInPPM").Value,
residueDefinition = a.Element("ResidueDefinition").Value,
additionalRegulationNotes = a.Element("AdditionalRegulationNotes").Value,
expiryDate = a.Element("ExpiryDate").Value,
primaryInd = a.Element("PrimaryInd").Value,
exemptInd = a.Element("ExemptInd").Value
}).ToList()
};

How to add one List into another List

I am trying to add one list into another but it is giving me error of The best overloaded method match for 'System.Collection.Generic.List.AddRange(System.Collections.Generic.IEnumerable)' has some invalid arguments
My code is:
public ActionResult RegisteredEvent(string Cno)
{
if (Request.IsAjaxRequest())
{
List<tblEvent> eventlist = new List<tblEvent>();
List<RegisteredEvent> list = new List<RegisteredEvent>();
var db = new clubDataContext();
int[] eventIds = (from m in db.EventRegistrations where m.Cno == Cno select m.Event_Id).ToArray();
int i = 1;
foreach (var item in eventIds)
{
list = (from m in db.tblEvents
where item.Equals(m.EventId)
select new RegisteredEvent()
{
id = m.EventId,
caption = m.Caption,
description = m.Description,
date = m.Date.ToString()
}).ToList();
eventlist.AddRange(list); //Here I am getting error
}
ViewBag.eventDetail = eventlist;
return PartialView("RegisteredEvent");
Simply speaking, you can only concatenate lists of the same type.¹
eventlist is a List<tblEvent>
list is a List<RegisteredEvent>
¹ This is not entirely correct: Since IEnumerable is covariant, it is actually possible to add entries of a List<S> to a List<T>, if S is a subtype of T.
The T in List<T> needs to have the same type or inherent from the same base type
List<RegisteredEvent> eventlist
List<RegisteredEvent> list
or
List<tblEvent> eventlist
List<tblEvent> list
You can use IEnumerable.Select as this (I don't know the structure of tblEvent, so adapt this at your code.
eventlist.AddRange(list.Select(x => new tblEvent{ id = x.id, caption = x.caption, ... }));
But the best way is to create directly a tblEvent
//the list sent to View
eventlist = (from m in db.tblEvents
where item.Equals(m.EventId)
select new tblEvent() //here
{
id = m.EventId,
caption = m.Caption,
description = m.Description,
date = m.Date.ToString()
}).ToList();

Create dynamic properties and bind hashtable in c#

I am trying to bind Row to gridview which will not only contain fields of Category table but other tables as well. So I had properties set for all those fields. But since the columns in the table could change frequently I need to dynamically change the properties as well. I found the following one way to do it (using hashtable). But I can't bind the hashtable values to gridview.
How to solve this problem better?
public partial class Form1 : Form
{
public class Row
{
// properties
public Hashtable Properties = new Hashtable();
}
public Form1()
{
InitializeComponent();
DataClasses1DataContext context = new DataClasses1DataContext();
var st = from c in context.Categories
select c;
var p = from pr in context.Products
select p;
Row r = new Row();
//List<Row> listrow = new List<Row>();
foreach (var item in st)
{
r.Properties.Add(item.Description, item.Description);
}
this.gridControl1.DataSource = r.Properties.Values;
}
}
Hashtable.Values is an ICollection - but you need IList to bind data. Ideally, you really want a typed list. Why use Hashtable at all here? I doubt you have enough rows to need it...
Instead, use a typed list (List<T> or BindingList<T>). Note that you can only bind to a single type in a grid. It isn't at all clear to me what you want to display in the grid, since at the moment you are only adding the description, but at the simplest level:
this.gridControl1.DataSource = context.Categories.ToList();
or (better):
this.gridControl1.DataSource = context.Categories.ToBindingList();
This won't help you put both Products and Categories into a single grid... but then, nothing will if they aren't the same type. One thing that might work is an anonymous type of the common properties:
var query = (from c in context.Categories
select new {Id = c.CategoryId, Name = c.Category,
Description = c.Description }).Concat(
from p in context.Products
select new {Id = p.ProductId, Name = p.Product,
Description = p.ProductDescription });
this.gridControl1.DataSource = query.ToList();
Note, however, that anonymous types are immutable (non-editable) - hence no point in using ToBindingList(). The other option is to declare your own class for the purpose, which means it can be editable too.

Categories

Resources