Firstly, you can make your query simpler by removing the "into x select x" at the end. Just leave it at the select new ...
part. You can also remove the brackets in the where
clause.
I'd also suggest simple casts for the ProductPrice and ProductAmount - in particular, converting the product price into a string before parsing sounds like a bad idea to me. What are the types of Price
and Quantity
in the first place?
Finally, it's generally a good idea to make the range variable name singular, as it's only applied to one item at a time:
var query = from product in pLDataContex.Products
where product.Id == p
select new OrderProductMapping
{
OrderId = insertedOrderId,
ProductId = p,
ProductPrice = (int) product.Price,
ProductQuantity = product.Quantity,
ProductAmount = (int) (product.Price * products.Quantity)
};
Now Query will be typed to IEnumerable<OrderProductMapping>
. Are you expecting a single result? If so, use one of:
Single()
- will throw if it doesn't get exactly one result
First()
- will throw if it doesn't get any results, will ignore any result after the first
SingleOrDefault()
- will throw if it gets more than one results, but return null if it doesn't get any
FirstOrDefault()
- will return null if it gets any results, will ignore any result after the first
I would suggest a call which will make the system throw in all the situations (and only the situations) which indicate a programming error. If it's expected that the product may not be found (e.g. the user has entered the ID) then SingleOrDefault()
is probably appropriate, assuming that Id
is a primary key. You'd write:
OrderProductMapping mapping = query.SingleOrDefault();
Then react appropriate based on whether mapping
is null or not.
EDIT: Reacting to the comment, the easiest way round this is to use an anonymous type, fetch the result of the query, and then build your desired result type from that:
var query = from product in pLDataContex.Products
where product.Id == p
select new
{
OrderId = insertedOrderId,
ProductId = p,
ProductPrice = (int) product.Price,
ProductQuantity = product.Quantity,
ProductAmount = (int) (product.Price * product.Quantity)
};
var anonMapping = query.SingleOrDefault();
if (anonMapping != null)
{
OrderProductMapping mapping = new OrderProductMapping
{
OrderId = anonMapping.OrderId,
ProductId = anonMapping.ProductId,
ProductPrice = anonMapping.ProductPrice,
ProductQuantity = anonMapping.ProductQuantity,
ProductAmount = anonMapping.ProductAmount
};
}
Note that this won't have general entity behaviour - if you modify the mapping, you'll have to explicitly save any changes to the database. I can't see that being an issue in this case though.
Another alternative is to use AsEnumerable
to perform the projection in process:
var query = pLDataContex.Products
.Where(product => product.Id == p)
.AsEnumerable()
.Select(product => new OrderProductMapping
{
OrderId = insertedOrderId,
ProductId = p,
ProductPrice = (int) product.Price,
ProductQuantity = product.Quantity,
ProductAmount = (int) (product.Price *
product.Quantity)
});