Check for data in database before delete - c#

I have these 2 forms (Add.aspx) "CalculationParameters" and "CalculationParametersValues". I also have 2 forms (Delete.aspx). These two forms are related. If there is no CalculationParameter, then you cannot add CalculationParametersValues. Now my problem is... when I delete a CalculationParameter, I want to check first if the CalculationParammeter has any CalculationParametersValues. I need to do this using this "=>" which is new to me, but I can't get the hang of it.
I get the values from database from here : "Factory.Definitions.CalculationParameters.List()" and "Factory.Definitions.CalculationParametersValues.List()".
It should be something like this (I think):
Factory.Definitions.CalculationParameters.List(item => (item.Id == <NOW here is where I should equal that Id with "CalculationParameterId">)
Help please ?

Assuming that you know which CalculationParameter is deleting and it's Id the solution will be:
var paramValues = Factory.Definitions.CalculationParametersValues.Where(p => p.Id == calculationParameter.Id);
Suggest reading this MSDN article. It is short and clear with nice examples for beginners.

// Add New Item
If (Factory.Definitions.CalculationParameters.List().Where(item => item.ID == NewItem.ID).Count == 0)
{
// Add new item to list
Factory.Definitions.CalculationParametersValues.List().Add(NewItem);
}
// Delete item
If (Factory.Definitions.CalculationParametersValues.List().Where(item => item.ID == DeleteItem.ID).Count == 0)
{
// No record in Values list ... Do something here
}
else
{
// Some records in Values list .. Do something here
}

Related

Is it possible to retrieve records from a database using an either all records or matching id method?

Basically I want to know if it is possible using as an example, Entity Framework, to retrieve all records from the DB table when the provided id doesn't match any of the id's in the table, but if there are id's that match then only retrieve those records.
It is possible to do obviously if you use an if statement or a ?: expression, as an example below.
var dbDocuments = new List<tblSalesQuoteDocument>();
if (id < 0)
dbDocuments = dbContext.tblSalesQuoteDocuments.ToList();
else
dbDocuments = dbContext.tblSalesQuoteDocuments.Where(x => x.HeaderId == id).ToList();
But I find this pretty ugly because if you want all records your URL is basically Documents/Index/-1 or any value less than 0.
Is there a better way?
Why I want one ActionResult is because I do a lot of filtering and code specific stuff in it. I could use two methods, 1 for all records, and another for specific records.
So should I do it as my question above or just use two methods and abstract all my filtering and other code away in Helper Methods to reduce code duplication?
You could add your filter expression on demand. Example:
ActionResult MyAction(int? id = null)
{
// ...
IQueryable<QuoteDocuments> docs = dbContext.tblSalesQuoteDocuments;
if (id != null)
{
docs = docs.Where(x => x.HeaderId == id.Value);
}
var list = docs.ToList();
// ...
}
docs = dbContext.tblSalesQuoteDocuments.Any(x => x.HeaderId == id)? dbContext.tblSalesQuoteDocuments.Where(x => x.HeaderId == id) : dbContext.tblSalesQuoteDocuments.ToList();
You should rather use
if(dbContext.tblSalesQuoteDocuments.Any(x => x.HeaderId == id)){
...
}

Is there any way through which we can update List records based on specified condition in C#, any customized method will also work except loop

lstStudents.First(m => m.Passed == "").PassoutYear= CurrentYear;
is there any other way to update records in bulk like the above statement which updates on the first record in list.
foreach (var student in lstStudents.Where(m => m.Passed == ""))
{
student.PassoutYear = CurrentYear;
}

Problems with DataContext not loading updated entity

I've stumbled upon a strange problem which I can't wrap my head around.
I have two DataContexts in two different forms. I created two "Customer" entities (Customer A and Customer Z) in one form and saved them through the form's context. I then went back to the other form, where I manage orders. In this form, I can create an order and search for a customer (or his address).
public void CustomerAddressSearched()
{
// Get all delivery addresses matching keyword
List<Address> addressList = customerModel.GetMatchingDeliveryAddresses(view.OrderSearchKeyword);
// If there is no matching address
if (addressList.Count == 0)
{
MessageBox.Show(Properties.Resources.SearchNoResult);
}
// If there is a single matching address
else if (addressList.Count == 1)
{
activeOrder.Address = addressList[0];
PopulateOrderAddressControls(addressList[0]);
activeOrderIsSaved = false;
}
// If there is more than one matching address, open search result view for user to pick address
else
{
using (var form = new CustomerSearchView(addressList))
{
if (form.ShowDialog() == DialogResult.OK)
{
CustomerViewObject selectedCustomer = (CustomerViewObject)form.selectedCustomer;
activeOrder.Address = addressList.Where(a => a.Id == selectedCustomer.AddressId).FirstOrDefault();
activeOrder.AddressId = selectedCustomer.AddressId;
PopulateOrderAddressControls(activeOrder.Address);
activeOrderIsSaved = false;
}
}
}
EnableOrDisableControls();
}
I searched for Customer and got a list with both customers. I went back to the customer form and changed the name of Customer A to Customer B, saved, then went back and searched again. Unfortunately, I got Customer A and Z as a result, not Customer B. Checked the database, Customer B is in it. I then picked Customer A for the order I created and saved it. Created a new one, searched again, and this time I got Customer B instead of A. I somehow need to use the "old" version once, otherwise the new one doesn't show. If this makes any sense.
So I checked
List<Address> addressList = customerModel.GetMatchingDeliveryAddresses(view.OrderSearchKeyword);
to see if there was something wrong with the way I retrieve the latest customer data.
public List<Address> GetMatchingDeliveryAddresses(string keyword)
{
List<Address> addressList = new List<Address>();
foreach (var c in context.Customers)
{
if (c.DateDeleted == null)
{
var result = c.Address.Where(a => (a.LastName.Contains(keyword) || a.Company.Contains(keyword)) && a.IsDeliveryAddress == true)
.OrderByDescending(a => a.DateEffective)
.FirstOrDefault();
if (result != null)
{
addressList.Add(result);
}
}
}
return addressList;
}
Sure enough, when debugging and stopping at the foreach loop, I noticed the latest version (Customer B) was not loaded (if I didn't use it at least once or restarted the program/created a new context).
I put
var list = context.Addresses.ToList();
right before the foreach loop just to check if he wouldn't load the new customer address at all, but all of a sudden it worked, the foreach loop loaded the newest customer version. I removed the line again and it stopped working. Put it back in, worked again. I guess my question is, why is the line above somehow refreshing my context, or whatever is happening?
Cheers!
Edit
I started went to the customer directory where I had two customers (Customer E and Customer 3). I renamed them to Customer ASD and Customer 666. Went back to the order form and searched for Customer. It ran the following code:
public List<Address> GetMatchingDeliveryAddresses(string keyword)
{
List<Address> addressList = new List<Address>();
foreach (var c in context.Customers)
{
var result = c.Address.Where(a => (a.LastName.Contains(keyword) || a.Company.Contains(keyword)) && a.IsDeliveryAddress == true)
.OrderByDescending(a => a.DateEffective)
.FirstOrDefault();
System.Console.WriteLine("PRE Name: " + result.LastName);
}
var list = context.Addresses.ToList();
foreach (var c in context.Customers)
{
var result = c.Address.Where(a => (a.LastName.Contains(keyword) || a.Company.Contains(keyword)) && a.IsDeliveryAddress == true)
.OrderByDescending(a => a.DateEffective)
.FirstOrDefault();
System.Console.WriteLine("POST Name: " + result.LastName);
}
With the following output:
PRE Name: Customer E
PRE Name: Customer 3
POST Name: Customer ASD
POST Name: Customer 666
I don't get it.
The question is getting too many comments, so I'm gonna post an answer here, cause I'm pretty sure that's the reason why you have this.. problem.
From what you've wrote in the comments: The context used to retrieve the customers is created when the form is initialized. I'm doing a context per form. it's getting clear that you are creating the context along with the form itself (probably in the constructor) and this is bad for many reasons. There are a lot of articles why you should NOT do that, but here we are talking for one certain problem and that's obviously the fact that your context is not changing until you close the form.
Now for your last comment - Turns out you were right, the code never made it to the dispose call for the customer directory context. But I still don't understand why it triggers such strange behaviour and how the line I added "fixed" it.
The reason is that DbContext is keeping track on all the changes that you make until the current context is alive, but it's just an expression tree (you could check what an expression tree is if you like) and in order to have some real data from that you need to execute certain calls. One of which is ToList() which forces the execution of the changes, but the quotes are really in place here, due to the fact that it's not how you are supposed to do it.
To keep it short. If you are not going to use any sort of data access layer, and just gonna use the DbContext directly inside your forms you should remove the context creation from the constructor (or where it is right now) and create new context each time (most probably for each method) that need to use. And in order to get rid of this problem you should wrap up tour code in using statement like so :
public List<Address> GetMatchingDeliveryAddresses(string keyword)
{
using( var context = new MyEntitiesContext())
{
List<Address> addressList = new List<Address>();
foreach (var c in context.Customers)
{
var result = c.Address.Where(a => (a.LastName.Contains(keyword) || a.Company.Contains(keyword)) && a.IsDeliveryAddress == true)
.OrderByDescending(a => a.DateEffective)
.FirstOrDefault();
System.Console.WriteLine("PRE Name: " + result.LastName);
}
foreach (var c in context.Customers)
{
var result = c.Address.Where(a => (a.LastName.Contains(keyword) || a.Company.Contains(keyword)) && a.IsDeliveryAddress == true)
.OrderByDescending(a => a.DateEffective)
.FirstOrDefault();
System.Console.WriteLine("POST Name: " + result.LastName);
}
}
And that should be all.

select from list which has same code

I have a problem in getting the values for the below.
I have a table called Retailers which contains Id,Description,Language and Code
I declared a list in my application which contains all the retailers list
var retailers = new List<Retailer>();
Now I need to add results of two retailers with same code so I am trying to do below and I am sure I am doing something wrong.
foreach (var retailer in retailers)
{
if (retailer.LanguageId != null)
{
// Here I am trying to findout if there are any other retailers who
// has same code if true then I need entire row of that retailer
**var retailerWithSameUacode = !retailers.Select(item => item.Code == retailerCode).SingleOrDefault();**
if (retailerWithSameUacode != null)
{
// Do something
}
}
}
Any help is much appreciated !
I don't think I entirely understand your question, but from your code comment and your attempt to select a retailer with the same code, I present to you the following..
To get the first retailer out of your list with a code that matches the current retailer, you would need to do this:
Retailer retailerWithMatchingCode = retailers.Where(r => r.Code == retailer.Code).FirstOrDefault();
You can then check the retailerWithMatchingCode object for a null value. If you just want to know if a retailer with a matching code exists, this is what you would do:
if (retailers.Any(r => r.Code == retailer.Code))
//Do something..
To get a list of retailers who have a matching "Code" property value, you would need to do this:
List<Retailer> retailersWithMatchingCode = retailers.Where(r => r.Code == retailer.Code).ToList();
Please note that this code is untested.
Try this solution:
var retailerWithSameUacode = retailers
.Where(item => item.LanguageId != null && item.Code == retailerCode)
.ToList();
foreach (var item in retailerWithSameUacode)
{
// Do something
}

LINQ within Razor to adjoining table

I am inside a foreach loop of my model. For every document I need to grab a note. The note is linked by documentID in both tables. I keep only getting Note type returned instead of the actual note.
#foreach ( var item in Model.document)
{
<span>#item.Table_Note.Where(n => n.documentid == item.documentid).Select(s => s.note)</span>
}
The above just returns the object. What am I doing wrong to be able to return the specific note from the table?
Try this instead:
#item.Table_Note.FirstOrDefault(n => n.documentid == item.documentid).note
This will fix your issue.
Alternately to handle null value you could use below as well:
#(item.Table_Note.FirstOrDefault(n => n.documentid == item.documentid) ?? new Table_Note()).note

Categories

Resources