C# DataContext returns null on comparing dates - c#

I am creating a database based desktop application and stuck in a problem..Actually I am new to Linq...
if (OP == "Delete")
{
tb = DB.TblPurchase.FirstOrDefault(e => e.PID.Equals(ID) || e.PItemName.Equals(ItemName) || e.PCategory.Equals(Category) || e.PDate.Equals(Date)); // returns null on comparing date
DB.Delete(tb);
return "Deleted";
}
else if (OP == "Search")
{
tb = DB.TblPurchase.FirstOrDefault(e => e.PID.Equals(ID) || e.PItemName.Equals(ItemName) || e.PCategory.Equals(Category) || e.PDate == Date); // returns null on comparing date as well
return tb;
}
Starting of the function :
`public object AUDS_Purchase(string OP, int? ID = null, string ItemName = "",string Category = "", string Supplier = "", DateTime? Date = null, int ? Rate = null, int? Quantity = null, int? Total = null)
{
using(var DB = new MYDBDB())
{
TblPurchase tb = null;`
Calling the function :
`dynamic _ID = Cmb_Search_ItemID.SelectedIndex == -1 ? null : Cmb_Search_ItemID.SelectedValue;
dynamic _ItemName = Cmb_Search_ItemName.SelectedIndex == -1 ? null : Cmb_Search_ItemName.SelectedValue.ToString();
dynamic _ItemCategory = Cmb_Search_ItemCategory.SelectedIndex == -1 ? null : Cmb_Search_ItemCategory.SelectedValue.ToString();
dynamic _Date = Search_Item_Date;
dynamic res;
if (Search_Item_Date.Checked == false)
{
if (_ID != null || _ItemName != null || _ItemCategory != null)
{
res = tb.AUDS_Inventory("Search", Convert.ToInt32(_ID), _ItemName, _ItemCategory);
tb.ShowNewData(metroGrid1, res);
}
else
{
MetroMessageBox.Show(this, "No Value Given\nSelect a value", "Error!", MessageBoxButtons.OK, MessageBoxIcon.Warning);
}
}
else
{
res = tb.AUDS_Inventory("Search", Convert.ToInt32(_ID), _ItemName, _ItemCategory, Date:_Date);
tb.ShowNewData(metroGrid1, res);
}`
Note : I am sure tb is null because I used breakpoint...
My table contains the records : Picture prove
Everything works fine with the database and the table...
This is my first post BTW..
Thanks In Advance :)

If the Date you are providing in the function contains different time then that might be the cause. As I can see from your database picture you are trying to compare date only. So you can try excluding time, it might work. You can try
e.PDate.Date == Date.Date in your function.

Related

Filter data from datatable for one of columns in asp.net

I have a datatable which fetches some records. So there is one column name as UPDATED_STATUS. In that column either Pre Hoto or Post Hoto value will come.
So what I want is, Either any one of those values should be their in that column then only the it should move ahead otherwise it should prompt alert as
Either Pre Hoto or Post Hoto can be their
Below is sample image for reference
Below is the code for getting the datatable with the UPDATED_STATUS column
if (strFlag == "")
{
dtStatus = GET_STATUS_FROM_SAPID_FOR_HOTO(dtExcelRows.Rows[i]["Current SAPID"].ToString());
if (dtStatus == null && dtStatus.Rows.Count < 0)
{
ClientScript.RegisterStartupScript(Page.GetType(), "erroralert", "alert('Status cannot be blank for SAP ID entered');", true);
}
else
{
dtExcelRows.Rows[i]["UPDATED_STATUS"] = dtStatus.Rows[0][1].ToString();
dtExcelRows.AcceptChanges();
}
}
Your current check (if (dtStatus == null && dtStatus.Rows.Count < 0)) is wrong:
when dtStatus is null, you continue checking dtStatus.Rows, which throws a nullref exception (you just found out that it was null);
Rows.Count is never less than zero.
Try if (dtStatus == null || dtStatus.Rows.Count == 0) to check whether there is no status at all (it is null) or no status rows (count is zero). The || will prevent checking for dtStatus.Rows when it was found that dtStatus is null.
&& means that both sides must be true at the same time.
|| means that at least of the sides must be true (both true is also fine).
Both don't evaluate the second test when the first already decided the outcome (false && whatever is always false, true || whatever is always true)
Are you looking for like this !
foreach (DataRow row in dtStatus.Rows)
{
if (string.IsNullOrEmpty(Convert.ToString(row["UPDATED_STATUS"])) ||
(Convert.ToString(row["UPDATED_STATUS"]).ToLower() != "pre hoto" &&
Convert.ToString(row["UPDATED_STATUS"]).ToLower() != "post hoto"))
{
ClientScript.RegisterStartupScript(Page.GetType(), "erroralert", "alert('Status cannot be blank for SAP ID entered');", true);
break;
}
else { }
}
I have got a way to get this done.. Here I go
if (strFlag == "")
{
dtStatus = GET_STATUS_FROM_SAPID_FOR_HOTO(dtExcelRows.Rows[i]["Current SAPID"].ToString());
if (dtStatus == null && dtStatus.Rows.Count < 0)
{
ClientScript.RegisterStartupScript(Page.GetType(), "erroralert", "alert('Status cannot be blank for SAP ID entered');", true);
}
else
{
dtExcelRows.Rows[i]["UPDATED_STATUS"] = dtStatus.Rows[0][1].ToString();
dtExcelRows.AcceptChanges();
}
}
}
DataTable dtGetHotoPre = null;
var rows = dtExcelRows.AsEnumerable().Where(x => x.Field<string>("UPDATED_STATUS") == "PRE HOTO");
if (rows.Any())
{
dtGetHotoPre = rows.CopyToDataTable();
}
DataTable dtGetHotoPost = null;
var rowsPost = dtExcelRows.AsEnumerable().Where(x => x.Field<string>("UPDATED_STATUS") == "POST HOTO");
if (rowsPost.Any())
{
dtGetHotoPost = rowsPost.CopyToDataTable();
}
string strFlagStatus = "";
if (dtGetHotoPre != null)
{
if (dtGetHotoPost != null)
{
strFlagStatus = "No Process";
}
else
{
strFlagStatus = "Process";
grdDvHoto.DataSource = dtGetHotoPost;
}
}
else
{
if (dtGetHotoPost != null)
{
strFlagStatus = "Process";
grdDvHoto.DataSource = dtGetHotoPre;
}
else
{
strFlagStatus = "No Process";
}
}
// if(dtGetHotoPre != null && dtGetHotoPost != null)
if (strFlagStatus == "No Process")
{
ClientScript.RegisterStartupScript(Page.GetType(), "erroralert", "alert('The sites contains both Pre and Post Hoto Status, so it cannot be uploaded');", true);
}
else
{
// will move ahead.
grdDvHoto.DataBind();
}

Can't implicity convert type 'string' error

I updated my code this but I always get a '0' value for REQ_INSP_APPROVAL field regardless. When a name should be value of 1 for that field and it still shows as 0:
W_USER usr = new W_USER
{
Name = Convert.ToString(dgvMaster.CurrentRow.Cells [dgvMaster.CurrentCell.ColumnIndex].Value)
};
//WINS_USER usr = Convert.ToString(o);
//IQueryable<WINS_USER> users = dc.CMB_USERs;
showLegend = loadedReports.Where(f => f.form.EXEMPTFROMIP == 0 && f.form.FORMHEADER.INSPAPPROVALPROCESS == 1 && f.form.SUPERAPPROVED == 1 && usr.REQ_INSP_APPROVAL == 1).Count() > 0;I updated the code to this:
if (dgvMaster.CurrentRow == null)
return;
object o = dgvMaster.CurrentRow.Cells[dgvMaster.CurrentCell.ColumnIndex].Value;
// Error on the following line
W_USER usr = Convert.ToString(dgvMaster.CurrentRow.Cells[dgvMaster.CurrentCell.ColumnIndex].Value);
showLegend = loadedReports.Where(f => f.form.EXEMPTFROMIP == 0 &&
f.form.FORMHEADER.INSPAPPROVALPROCESS == 1 &&
f.form.SUPERAPPROVED == 1 &&
usr.REQ_INSP_APPROVAL == 1)
.Count() > 0;
Also in my designer class file I updated the REQ_INSP_APPROVAL from this
[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_REQ_INSP_APPROVAL", DbType="Int")]
public System.Nullable<int> REQ_INSP_APPROVAL
{
get
{
return this._REQ_INSP_APPROVAL;
}
set
{
if ((this._REQ_INSP_APPROVAL != value))
{
this.OnREQ_INSP_APPROVALChanging(value);
this.SendPropertyChanging();
this._REQ_INSP_APPROVAL = value;
this.SendPropertyChanged("REQ_INSP_APPROVAL");
this.OnREQ_INSP_APPROVALChanged();
}
}
}
to
[global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_REQ_INSP_APPROVAL", DbType="Int")]
public int REQ_INSP_APPROVAL
{
get
{
return this._REQ_INSP_APPROVAL;
}
set
{
if ((this._REQ_INSP_APPROVAL != value))
{
this.OnREQ_INSP_APPROVALChanging(value);
this.SendPropertyChanging();
this._REQ_INSP_APPROVAL = value;
this.SendPropertyChanged("REQ_INSP_APPROVAL");
this.OnREQ_INSP_APPROVALChanged();
}
}
}
Before updating I was getting null for the REQ_INSP_APPROVAL now I'm getting as I stated '0'.
I know this is a lot but I really need help.
What is W_USER? Seems like W_USER is a class and you are trying to store a string value in the object of the class. That's why it is throwing you error. store below in a string variable.
W_USER usr=new W_USER(); usr.Name=Convert.ToString(dgvMaster.CurrentRow.Cells[dgvMaster.CurrentCell.ColumnIndex].Value);

Due to LINQ Retrieving of Record data's i have this error: NullReferenceException was unhandled by user code

private void getUserLoginDepartment(string AccessID, string UserPROFid)
{
try
{
DBWPAccountRecordsDataContext DBACCOUNT = new DBWPAccountRecordsDataContext();
var query = (from i in DBACCOUNT.WP_UserAccessPorts
join
z in DBACCOUNT.WP_Departments on i.AccessPortID equals z.Dept_ID
where i.AccessPortID == AccessID && i.ProfileUser_ID == UserPROFid
select new
{
PORT1 = i.AccessPoint1,
PORT2 = i.AccessPoint2,
PORT3 = i.AccessPoint3,
PORT4 = i.AccessPoint4,
DEPT = z.Dept_DESC,
DEPTPORT = z.Dept_PortNo
}).FirstOrDefault();
if (query.PORT1.ToString() != null || query.PORT1.ToString() != string.Empty)
{ Session["Port1"] = query.PORT1; }
else { Session["Port1"] = ""; }
if (query.PORT2.ToString() != null || query.PORT2.ToString() != string.Empty)
{ Session["Port2"] = query.PORT2; }
else { Session["Port2"] = ""; }
if (query.PORT3.ToString() != null || query.PORT3.ToString() != string.Empty)
{ Session["Port3"] = query.PORT3; }
else { Session["Port3"] = ""; }
if (query.PORT4.ToString() != null || query.PORT4.ToString() != string.Empty)
{ Session["Port4"] = query.PORT4; }
else { Session["Port4"] = ""; }
}
finally
{
}
}
The Error occures when i reach break point 1st IF Statement the record on my database shows that its not empty which its value is "WebAdmin" but then suppost to be it should pick it up and store it to the Session["PORT1"] that i have made is there something i missed or i'm doing it wrong on my linq Query. NOTE:*This is an ASP.NET C# Application
EDIT 10/2/2013 0420PM:
It's still an Error After using that method sir.
1) you should check query for null when you use FirstOrDefault
2) you need to check each PORTX for null
3) use string.IsNullOrEmpty( ) to check if the string of PORTX is null
var query = ( ... ).FirstOrDefault( );
if( query != null )
{
if( query.PORT1 != null && !string.IsNullOrEmpty( query.PORT1.ToString( ) ) )
{
}
else { ... }
}
You have to check query.PORT1 for null before calling ToString on it, you can use String.IsNullOrEmpty to check both conditions. Before checking query.PORT1 you need to check if query is null or not. You also need to use && instead of or operator as || will cause the right side of or operator to be evaluated if left is false and on right side calling ToString on null will again through exception.
if (query != null && query.PORT1 != null && query.PORT1.ToString() != string.Empty)
{ Session["Port1"] = query.PORT1; }
Using IsNullOrEmpty
if(query != null && !String.IsNullOrEmpty(query.PORT1))
{
Session["Port1"] = query.PORT1;
}

Entity Framework 5 doesn't update Many to Many relation

I have the following tables in an SQL2008 database:
Accommodation
code varchar(18)
name varchar(80)
This table has more columns but I have removed them here for simplicity.
Attributes
code int
name varchar(50)
AccommodationAttributes
AccommodationCode varchar(18)
AttributeCode int
As you may get, AccommodationAttributes describes the many to many relationship between Accommodations and Attributes.
I have created my model (EF5) using database first, and it has created two classes linked with a navigation property.
All this seems correct.
What I am trying to do is add values in the db, but though I am able to add Accommodations and Attributes, I don't seem to be able to make it add the corresponding values in the AccommodationAttributes table.
I am reading from an XML file.
EDIT
Below is the code I am using exactly as it is:
public static void UpdateAccommodation(string file)
{
InterHomeEntities ih = new InterHomeEntities();
Stopwatch sw = new Stopwatch();
ih.Configuration.AutoDetectChangesEnabled = false;
ih.Configuration.ValidateOnSaveEnabled = false;
ih.Configuration.LazyLoadingEnabled = false;
XElement xe = XElement.Load(file);
DateTime DayToProcess = DateTime.Now.AddDays(Properties.Settings.Default.InterHome_DaysToProcess);
var Attributes = xe.XPathSelectElements("//attribute").Select(x => x.Value).Distinct();
foreach (var attribute in Attributes)
{
Attribute at = ih.Attributes.Where(x => x.name == attribute).SingleOrDefault();
bool newEntry = at == null ? true : false;
at = newEntry ? new Attribute { name = attribute } : at;
ih.Attributes.Attach(at);
ih.Entry(at).State = newEntry ? System.Data.EntityState.Added : System.Data.EntityState.Modified;
ih.SaveChanges();
}
var Accommodations = from c in xe.Elements("accommodation") select c;
int AccomodationCount = Accommodations.Count();
int AccomodationIndex = 0;
foreach (var accommodation in Accommodations)
{
AccomodationIndex++;
var AccCode = accommodation.Element("code").Value;
try
{
Accommodation a = ih.Accommodations.Where(x=>x.code == AccCode).SingleOrDefault();
bool newAccommodation = a == null ? true : false;
a = !newAccommodation ? a :
new Accommodation
{
code = accommodation.Element("code") == null ? null : accommodation.Element("code").Value,
name = accommodation.Element("name") == null ? null : accommodation.Element("name").Value,
country = accommodation.Element("country") == null ? null : accommodation.Element("country").Value,
region = accommodation.Element("region") == null ? null : accommodation.Element("region").Value,
place = accommodation.Element("place") == null ? null : accommodation.Element("place").Value,
zip = accommodation.Element("zip") == null ? null : accommodation.Element("zip").Value,
type = accommodation.Element("type") == null ? null : accommodation.Element("type").Value,
quality = accommodation.Element("quality") == null ? (byte?)null : Convert.ToByte(accommodation.Element("quality").Value),
details = accommodation.Element("details") == null ? null : accommodation.Element("details").Value,
brand = accommodation.Element("brand") == null ? null : accommodation.Element("brand").Value,
pax = accommodation.Element("pax") == null ? (double?)null : Convert.ToDouble(accommodation.Element("pax").Value),
sqm = accommodation.Element("sqm") == null ? (double?)null : Convert.ToDouble(accommodation.Element("sqm").Value),
floor = accommodation.Element("floor") == null ? (double?)null : Convert.ToDouble(accommodation.Element("floor").Value),
rooms = accommodation.Element("rooms") == null ? (double?)null : Convert.ToDouble(accommodation.Element("rooms").Value),
bedrooms = accommodation.Element("bedrooms") == null ? (double?)null : Convert.ToDouble(accommodation.Element("bedrooms").Value),
toilets = accommodation.Element("toilets") == null ? (double?)null : Convert.ToDouble(accommodation.Element("toilets").Value),
bathrooms = accommodation.Element("bathrooms") == null ? (double?)null : Convert.ToDouble(accommodation.Element("bathrooms").Value),
lat = accommodation.Element("geodata") == null || accommodation.Element("geodata").Element("lat") == null ? null : accommodation.Element("geodata").Element("lat").Value,
lng = accommodation.Element("geodata") == null || accommodation.Element("geodata").Element("lng") == null ? null : accommodation.Element("geodata").Element("lng").Value,
LastUpdated = DateTime.Now
};
foreach (var attribute in accommodation.Elements("attributes").Elements("attribute").Select(x=>x.Value))
{
Attribute at = ih.Attributes.Where(x => x.name == attribute).SingleOrDefault();
a.Attributes.Add(at);
}
if (newAccommodation)
{
ih.Accommodations.Add(a);
}
else
{
ih.Entry(ih.Accommodations.Where(x => x.code == a.code).SingleOrDefault()).CurrentValues.SetValues(a);
ih.Entry(ih.Accommodations.Where(x => x.code == a.code).SingleOrDefault()).State = System.Data.EntityState.Modified;
}
ih.SaveChanges();
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
}
ih.SaveChanges();
}
After running this code I run the following in SQL:
select COUNT(*) from Accommodations
select COUNT(*)from Attributes
select COUNT(*)from AccommodationAttributes
But though I see entries in the two tables, the link table comes with 0 rows.
I have tried other variations, like attaching the objects to the context, or implicitly specifying that it is a modified object.
By the time that this code will run I am sure that the Attributes are already inserted in the db, but the Accommodation is either an Insert or Update.
UPDATE
After further investigation, it seems that it works when I add a new Accommodation, but it fails when the Accommodation is already in the db and I just add new attributes. In my case in the process of developing I had first added the Accommodation and in a later step of development I created the process to import attributes. So I need to find a way to update the relationship when both accommodation and attribute are already in the db.
I am eager to hear your thoughts,
Giannis
make sure you set the following:
In table Accomodation PK is code.
In table Attrrrribute PK is code.
In table AccomodationAtrribute PK is AccomodationCode+AttributeCode.
In table AccomodationAttribute set a foriegn key of AccomondationCode to colum code in table Accomodation.
In table AccomodationAttribute set a foriegn key of AttributeCode to colum code in table Attribute.
also for the linking table to be filled you need to link an attribute instance to an accomodation or vice versa in the code. somtheing like:
accomodation.Attrbutes.Add(attribute);

linq conditional query

What would be the best practice for setting a status depending on several other "columns" retrieved in a linq query.
var result = (from q in query
select new Item
{
ApprovedDate = q.ApprovedDate,
CreatedDate = q.CreatedDate,
DeclinedDate = q.DeclinedDate,
Status = 0
});
I'd like to set the status to either 0, 1, 2.
(ApprovedDate == null and DeclinedDate == null) --> 0
(ApprovedDate != null and DeclinedDate == null) --> 1
(DeclinedDate != null) --> 3
So perhaps something like:
var result = (from q in query
select new Item
{
ApprovedDate = q.ApprovedDate,
CreatedDate = q.CreatedDate,
DeclinedDate = q.DeclinedDate,
Status = (q.CreatedDate == null && q.DeclinedDate == null) ? 0 : (q.ApprovedDate != null && q.DeclinedDate == null) ? 1 : 2
});
I might add even more status combinations, so should I try and do this in the linq select query, in my repository object.. Or later on in the controller where I would do a .ToList() and then foreach the list to set the correct status code?
Having even more than 3 statuscodes, the linq query gets "hard" to read.
What about moving status calculation to Item class? If status property depends on other properties value, then it's definitely calculated property:
var result = from q in query
select new Item
{
ApprovedDate = q.ApprovedDate,
CreatedDate = q.CreatedDate,
DeclinedDate = q.DeclinedDate
});
And
public class Item
{
// other properties
public int Status
{
get
{
if (ApprovedDate == null and DeclinedDate == null)
return 0;
if (ApprovedDate != null and DeclinedDate == null)
return 1;
if (DeclinedDate != null)
return 3;
// etc
}
}
}
Actually I think it's best option, because in this case status calculation logic will be close to required data. If (for some reason) you can't use this approach, then move setting statuses to local items collection:
var items = result.ToList().ForEach(i => i.Status = CalculateStatus(i));
Maybe wrapped all in a function An do a linq like this
var result = (from q in query sele q).AsEnumerable()
.Select( x => new Item()
{
ApprovedDate = x.ApprovedDate,
CreatedDate = x.CreatedDate,
DeclinedDate = x.DeclinedDate,
Status = MyStatusFunction(x.CreatedDate,q.DeclinedDate)
});
public int MyStatusFunction(DateTime ApprovedDate , Datetime DeclinedDate)
{
if (ApprovedDate == null and DeclinedDate == null) return 0;
else if(ApprovedDate != null and DeclinedDate == null) return 1;
else if (DeclinedDate != null) return 3;
}

Categories