Check if string already exist in Table - c#

I want to check if the email that user entered already exist in Office table,take a look bellow what I have done so far, the problem is that officeEmail is always true, even though the entered email doesn't exist it's never returning NULL.
public static bool IsOfficeEmail(string email)
{
using (var data = Database)
{
data.ObjectTrackingEnabled = false;
var officeEmail = data.Offices.Where(a => a.Active && a.Email.Equals(email));
if (officeEmail != null)
return true;
}
return false;
}

Where will not return you null, but empty sequence, change it to:
var officeEmail = data.Offices.FirstOrDefault(a => a.Active && a.Email.Equals(email));
if (officeEmail != null)
return true;
FirstOrDefault will return default value (here null) it will not find queried value.
It is an option to use Any if you are not interested in email record:
public static bool IsOfficeEmail(string email)
{
using (var data = Database)
{
return data.Offices.Any(a => a.Active && a.Email.Equals(email))
}
}
You will not get email record if you will not use it anyway. Which approach you should use depends on what will you do with officeEmail, if you are just querying if it exists -> Any will be the best approach here. If you would like to get check for existing record and do something with it, FirstOrDefault will be better.

Alternativly if you really want to use .Where you can also check if the returned collection contains ANY elements:
if (officeMail.Any()) // ...
Or even shorter:
if (officeMail.Any(a => a.Active && a.Email.Equals(email))) // ...
If you want to ensure that there is exactly ONE item within your list matching your condition use .Single instead of .Any which will throw an exception if none or more then one item was found.
The actual reason for your check allways returning true is that .Where will return an enumerator even when no item matches the condition. Therefor the result is never null.

Related

Find string in a List, if match, string = List name

So my gameobject string name contain an ID(first variable) in the List, since the List is a custom class with two variable. I want to switch the name gameobject name to the second
variable after comparing the first variable and returning True.
if (gameData_List.showing_my_loading_list.Any(s => anchor.name.Contains(s.guid.ToString())))
{
Debug.Log("Found)
}
The result show 4 found, but what I'm trying to do is after knowing that is true, change the anchor.name to s.SecondVarible.Tostring();
However, after I set the condition in the if,
I no longer have access to the (s) in the Debug.Log area.
I managed to solve it myself, thanks
var temp = gameData_List.showing_my_loading_list.Find(x => anchor.name.Contains(x.guid.ToString()));
if (temp != null)
{
anchor.name = temp.readable_guid;
Debug.Log("Changing Name");
}
If you do not want to split it into lines you could probably do something like
anchor.name = gameData_List.showing_my_loading_list.FirstOrDefault(s => anchor.name.Contains(s.guid.ToString()))?.readable_guid ?? anchor.name;
So this does
FirstOrDefault: Try to find an element s where the condition is matched or return default (= null for classes)
?.: If it is not null use the readable_guid, otherwise return null again
??: If the before is null use anchor.name (the old one) as fallback => change nothing
Of course this loses the ability to do more things when you found a valid element like your logging etc.
Alternatively, why not simply stick to a normal loop ;)
foreach(var s in gameData_List.showing_my_loading_list)
{
if(anchor.name.Contains(s.guid.ToString())
{
anchor.name = s.readable_guid;
Debug.Log("Changing Name");
break;
}
}
or with Linq again
foreach (var s in gameData_List.showing_my_loading_list.Where(s => anchor.name.Contains(s.guid.ToString())))
{
anchor.name = s.readable_guid;
Debug.Log("Changing Name");
break;
}
gameData_List.showing_my_loading_list.filter(s => anchor.name.Contains(s.guid.ToString())).each(() => {
Debug.Log("Found)
})

After checking if a record exist, and it doesn't, SaveChanges gives an DbUpdateException

I have a table that has a unique index on two columns, F1 and Kant[1]. There is no Foreign Keys just Primary Key (which is an integer Id) and this index.
Before I add a new record I do a check if a record with this index exists in the database.[2]
I get that it doesn't! ExistsLaserData returns false.
I then add the record to the DbSet and execute SaveChanges but now I get an exception
DbUpdateException: SqlException: Violation of UNIQUE KEY constraint
'IX_laserdata_F1_Kant'. Cannot insert duplicate key in object
'dbo.LaserData'. The duplicate key value is (123456, NULL).
This is the record I have added!
The context is initialized with
LaserDataContext context = new LaserDataContext();
OrderBy(x => x.F1).ThenBy(x => x.Kant).ToList();
The two methods that I'm using
public bool ExistsLaserData(string article, string kant)
{
bool result = false;
var found = _context.LaserData.Where(x => x.F1 == article && x.Kant == kant).FirstOrDefault();
if (found != null)
{
result = true;
}
return result;
}
public void AddLaserData(ref LaserData d)
{
try
{
_context.LaserData.Add(d);
_context.SaveChanges();
}
catch (Exception ex)
{
throw;
}
}
Why does the record not exist when I check for it or why does it exist when I do SaveChanges?
[1] The beginning of this database was an Excel document, thus the strange names...
[2] I don't want to skip the ExistLaserData check, so please don't suggest that I should just use the exception.
Here you are checking for both the values in the same row and it returns a row only if both the keys are the same for a single row.
Can you try this? Instead of && , use ||
public bool ExistsLaserData(string article, string kant)
{
bool result = false;
var found = _context.LaserData.Where(x => x.F1 == article || x.Kant == kant).FirstOrDefault();
if (found != null)
{
result = true;
}
return result;
}
I think you should cast the article to integer then check if that exists or not.
As you said F1 is int and article is string so you can not compare them.
Then you can use this for add or update :
LaserData found = _context.LaserData.FirstOrDefault( p => p.F1==(int) article);
if(found == null)
{
_context.LaserData.Add(d);
_context.SaveChanges();
}
I hope this helps you. maybe you need to explain more if this is not you want.
if the article type is like F1 so u can write without cast to int :
LaserData found = _context.LaserData.FirstOrDefault( p => p.F1== article);
You do not have to check kant if it is not unique. But you can check if u like.
Edit :
just use this :
public bool ExistsLaserData(string article, string kant)
{
bool result = false;
LaserData found = _context.LaserData.FirstOrDefault(x => x.F1 == article && x.Kant == kant);
if (found != null)
{
result = true;
}
return result;
}
More likely than not your kant property is not properly mapped. This would explain both the Exception and the behavior of the code.
The Exception states you tried to insert a null value for kant which would make sense because EF never sent over a value due to the incorrect mapping.
ExistsLaserData always returns false as long as you do not pass null into the method for the kant parameter. This would lead your code to always try the AddLaserData method.
So the fix is to ensure that this property is properly mapped and to correct column.
If that is not it then you are trying to insert multiple records with the same F1 value but with a null kant value which would break the unique index. The only way around that is to alter the index with a where filter so that it only checks when the kant has a value.
CREATE UNIQUE NONCLUSTERED INDEX [IX_laserdata_F1_Kant] ON dbo.LaserData (F1 ASC, Kant ASC) WHERE (Kant IS NOT NULL)
OK, I have found where the error occurs and it has nothing to do with the ExistsLaserData to do. ExistsLaserData works perfectly!
since this is a whole new problem I will make a new question
Thanks for all of your suggestions, I will use some of them!
PS! As a teaser. In the override of SaveChanges event I Trim() all fields that are strings. This does something that make the base.SaveChanges throw an exception...

If Element does not exist

I have around a dozen solutions to this, but none seem to fit what I am trying to do. The XML file has elements that may not be in the file each time it is posted.
The trick is, the query is dependent upon a question value to get the answer value. Here is the code:
string otherphone = (
from e in contact.Descendants("DataElement")
where e.Element("QuestionName").Value == "other_phone"
select (string)e.Element("Answer").Value
).FirstOrDefault();
otherphone = (!String.IsNullOrEmpty(otherphone)) ? otherphone.Replace("'", "''") : null;
Under the "contact" collection, here are many elements named "DataElement", each with its own "QuestionName" and "Answer" elements, so I query to find the one where the element's QuestionName value is "other_phone", then I get the Answer value. Of course I will need to do this for each value I am seeking.
How can I code this to ignore the DataElement containing QuestionName with value of "other_phone" if it doesn't exist?
You can use Any method to check whether or not the elements exists :
if(contact.Descendants("DataElement")
.Any(e => (string)e.Element("QuestionName") == "other_phone"))
{
var otherPhone = (string)contact
.Descendants("DataElement")
.First(e => (string)e.Element("QuestionName") == "other_phone")
.Element("Answer");
}
Also, don't use Value property if you are using explicit cast.The point of explicit cast is avoid the possible exception if the element wasn't found.If you use both then before the cast, accessing the Value property will throw the exception.
Alternatively, you can also just use the FirstOrDefault method without Any, and perform a null-check:
var element = contact
.Descendants("DataElement")
.FirstOrDefault(e => (string)e.Element("QuestionName") == "other_phone");
if(element != null)
{
var otherPhone = (string)element.Element("Answer");
}
So you want to know if other_phone exists or not?
XElement otherPhone = contact.Descendants("QuestionName")
.FirstOrDefault(qn => ((string)qn) == "other_phone");
if (otherPhone == null)
{
// No question with "other_phone"
}
else
{
string answer = (string)otherPhone.Parent.Element("Answer");
}

Not all code paths return a value

I am having this Linq To SQL query which is taking Customer Category from database.The CustCategory will be defined already.Here is the query.
public IList<string> GetAccountType()
{
using (var db = new DataClasses1DataContext())
{
var acctype = db.mem_types.Select(account=>account.CustCategory).Distinct().ToList();
if (acctype != null)
{
return acctype;
}
}
}
Currently I am getting an error that Not all code paths return a value.If I am always certain that the value is there in the database then do I need to check for null,If I need to check for null then how do I handle this.
Can anyone help me with this.
Any suggestions are welcome.
Since Enumerable.ToList never returns null (see the Return Value section of the documentation), you can safely remove the if.
EDIT: Note that, no matter what your database contains, acctype will never be null:
If no value is found in the database, the return value will be an empty list (which is different than null).
If one record is found and its value is null, the return value will be a valid list with one entry, whose value is null. Still, the list itself is not null.
What happens if:
if (acctype != null)
Is null? What is your method supposed to return?
You need to return something
This is not about LINQ to SQL, the method GetAccountType() must return IList<string>. You should return return acctype; and then check this returned list later using Any(), something like:
if(GetAccountType.Any()){
//not empty
}
How about something like this for a fairly clean and readable solution?:
(Note, updated: removed the check for null, since it would clearly not have any effect).
public IList<string> GetAccountType()
{
var acctype = new List<string>();
using (var db = new DataClasses1DataContext())
{
acctype = db.mem_types.Select(
account=>account.CustCategory).Distinct().ToList();
}
return acctype;
}
You need to return a value from your function:
public IList<string> GetAccountType()
{
using (var db = new DataClasses1DataContext())
{
var acctype = db.mem_types.Select(account=>account.CustCategory).Distinct().ToList();
if (acctype != null)
{
return acctype;
}
}
return acctype;
}

C# Elegant way to handle checking for an item in a collection

I've posted a code sample below. Firstly let me explain
termStore.Groups in the code below is a collection of Group Objects (The exact class is irrelevant).
Checking for null : if (termStore.Groups[groupName] == null) seems like a logical (clean) approach, but if the Groups collection is empty then an exception is produced.
using the termStore.Groups.Contains is not an option either because this expects a strong type i.e: .Contains(Group)... not .Contains(GroupName as string)
Can someone recommend a clean / generic way I can check for if an item exists in collection .
Thank you....
TermStore termStore = session.TermStores.Where(ts => ts.Name == termStoreName).FirstOrDefault();
if (termStore.Groups[groupName] == null)
{
termStore.CreateGroup(groupName);
termStore.CommitAll();
}
Update: The exact class Sharepoint Taxonomy Classes. http://msdn.microsoft.com/en-us/library/microsoft.sharepoint.taxonomy.group.aspx
Update 2, the exact collection : http://msdn.microsoft.com/en-us/library/microsoft.sharepoint.taxonomy.groupcollection.aspx
Microsoft.SharePoint.Taxonomy.GroupCollection implements IEnumerable<Group>, so a bit of LINQ is probably just what the doctor ordered:-
if(termStore.Groups.Any(x => x.Name == "MyGroup"))
{
// group contains at least one item matching the predicate.
}
else
{
// group contains no items matching the predicate.
}
You'll need to be using .NET 3.5 or better and add "using System.Linq;" to the top of your file.
Edit
If you don't have LINQ available, or if it offends you, or if you've genuinely profiled and found that iterating over Groups is killing performance compared to the string indexer, you could use GroupCollection.Count to avoid the error state:-
if (termStore.Groups.Count == 0 || termStore.Groups[groupName] == null)
{
// Group doesn't exist.
}
IEnumerable.Any(...) should work for your case:
termsStore.Groups.Any()
I think this is what you are looking for:
termStore.Groups.ContainsKey(groupName)
Checks that the key exists, doesn't throw an exception if it doesn't. This is assuming that Groups is a collection that implements IDictionary.
May be this
termStore.Any() && termStore.Groups.Any() && termStore.Groups[groupName] == null
Ok, 2nd attempt. If Groups doesn't contain the required ContainsKey method then you can write it yourself. Then you can just use ContainsKey in place of Contains.
static class GroupExtensions
{
public static bool ContainsKey(this Groups groups, string key)
{
try
{
if(groups[key] == null)
{
return false;
}
}
catch
{
return false;
}
return true;
}
}

Categories

Resources