if else statement inside a local variable/class - c#

Why cannot I use if else statement inside this local variable account? Inside the "if" I'm planning to enter the code IsActive = "Yes", then inside the "else" IsActive = "No". But the IsActive string that I declared in the class is not appearing/suggesting.
private void btnAdd_Click(object sender, EventArgs e)
{
UserAccount account = new UserAccount()
{
FirstName = txtFirstName.Text,
LastName = txtLastName.Text,
Email = txtEmail.Text,
TeamName = txtTeamName.Text,
Password = txtPassword.Text,
// IsActive = "Yes",
if (chkIsActive.Checked == true)
{
}
else
{
}
UserId = int.Parse(txtUserId.Text)
};
}

You can't use an if else statement inside an object initialization. You can only assign to public writable (that is, properties having a setter) properties there.
As suggested in one comment below, starting from C# 9 you can also set init-only properties when using object initialization syntax. These properties can be written only during object construction, once the object construction phase is completed you are not allowed to write the property.
Regardless of the C# language version, you can't use any control flow statement in object initialization.
A working version of your code is the following:
string isActive = chkIsActive.Checked ? "Yes": "No";
var account = new UserAccount()
{
FirstName = txtFirstName.Text,
LastName = txtLastName.Text,
Email = txtEmail.Text,
TeamName = txtTeamName.Text,
Password = txtPassword.Text,
IsActive = isActive,
UserId = int.Parse(txtUserId.Text)
};

You are trying to use control statement inside the class initializer. You cannot do that.
You can use ternary operator.
UserAccount account = new UserAccount()
{
FirstName = txtFirstName.Text,
LastName = txtLastName.Text,
Email = txtEmail.Text,
TeamName = txtTeamName.Text,
Password = txtPassword.Text,
//IsActive = "Yes",
IsActive = chkIsActive.Checked ? "Yes" : "No",
UserId = int.Parse(txtUserId.Text)
};
Don't use boolVariable == true, just use boolean itself. Only exception is a nullable boolean.

You can do this a few ways, the following is an example of using a ternary condition to set the property value:
private void btnAdd_Click(object sender, EventArgs e)
{
UserAccount account = new UserAccount()
{
FirstName = txtFirstName.Text,
LastName = txtLastName.Text,
Email = txtEmail.Text,
TeamName = txtTeamName.Text,
Password = txtPassword.Text,
IsActive = chkIsActive.Checked ? "Yes" : "No",
UserId = int.Parse(txtUserId.Text)
};

Related

SQLite on C#. Select query does not work with string of letters

I'm learning C# since the past week and databases since a couple of days ago, so if you see something dodgy and you ask yourself "Why did he do that like that?", the answer is probably going to be "Because that's all I know for the moment".
In the title I said "of letters" because if I use a string of numbers, it works.
I have a tiny database with three columns. Id (int), FirstName (text) and LastName (text).
Id is unique, primary key and autoincrements. FirstName is unique. The three are not null.
In that database I have two records:
Id FirstName LastName
3- 6666 2222
4- Test O'Test
This is my method:
public static bool isOnDb(string nombre, string apellido)
{
bool flag = false;
{
try
{
using (IDbConnection cnn = new SQLiteConnection(LoadConnectionString()))
{
string tempName = "Test"; // This is temporarily replacing the argument 'nombre'
int tempNum= 3; // More testing. See below
//cnn.Query<Person>($"select * from Person where FirstName = { tempName }", new DynamicParameters());
// This four lines below are just for testing. They are going to be deleted
var output = cnn.Query<Person>($"select * from Person where FirstName = { tempName }", new DynamicParameters());
var person = output.First();
Console.WriteLine("Funciona");
Console.WriteLine($"{ person.Id } - { person.FullName }");
flag = true;
return flag;
}
}
catch (Exception)
{
Console.WriteLine("Derecho a excepcion");
return flag;
}
}
}
Basically, if tempName = "Test", it falls into an exception. But if tempName = "6666" it returns the row.
I also tried selecting by id. That's why tempNum is there.
int tempNum= 4;
var output = cnn.Query<Person>($"select * from Person where Id = { tempNum }", new DynamicParameters());
Well in SQLite the strings are signified by '' so when you pass FirstName = { tempName } and its FirstName = Test it looks for the column called Test in Table person rather than equating it to the 'Test' string
So you can do:
var output = cnn.Query<Person>($"select * from Person where FirstName = '{ tempName }'");
Or better yet:
var people = cnn.Query<Person>("SELECT * FROM PERSON WHERE FirstName = #FirstName", new { FirstName = tempName });

F#: Why those two collections are not equal?

Was writing some units using XUnit until that at some points I bumped into something surprising:
let id = Guid.Empty
let contact = {
Name = {
FirstName = "Marcel"
MiddleInitial = None
LastName = "Patulacci"
}
DateOfBith = new DateTime(1850, 12, 25)
Address = {
Address1 = "41 av 8 Mai 1945"
Address2 = None
City = "Sarcelles"
State = None
Zip = "95200"
}
PhoneNumber = {
DialOutCode = 33
LocalNumber = "766030703"
}
Email = "marcel.patulacci#outlook.com"
}
[<Fact>]
let ``Open an account...``() =
let event = Event.AccountOpened({
AccountId = id
Contact = contact
})
let a = [event]
let b = seq { yield event }
Assert.Equal(a, b)
System.NullReferenceException : Object reference not set to an instance of an object.
It seems surprising especially since considering that the overload used by Assert is:
public static void Equal<T>(IEnumerable<T> expected, IEnumerable<T> actual)
Which states that:
Verifies that two sequences are equivalent, using a default comparer.
Why are they considered different, and why does Assert.Equal raise a System.NullReferenceException?
[EDIT]
System.NullReferenceException : Object reference not set to an instance of an object.
at Domain.Events.AccountOpenedEvent.Equals(Object obj, IEqualityComparer comp)
at Domain.Events.Event.Equals(Object obj, IEqualityComparer comp)
Seems
type PersonalName = {
FirstName: string;
MiddleInitial: string option;
LastName: string;
}
type Address = {
Address1: string;
Address2: string option ;
City: string;
State: string option;
Zip: string;
}
type PhoneNumber = {
DialOutCode : int;
LocalNumber: string
}
type Contact = {
Name: PersonalName;
DateOfBith: DateTime
Email: string;
Address: Address;
PhoneNumber: PhoneNumber
}
type AccountOpenedEvent = {
AccountId: Guid
Contact: Contact
}
type Event =
| AccountOpened of AccountOpenedEvent
It turns out one of the fields of event was null, but not event itself.
The problem resided in the id and contact that were defined right above the test / [<Fact>]:
let id = Guid.Empty
let contact = {
Name = {
FirstName = "Marcel"
MiddleInitial = None
LastName = "Patulacci"
}
DateOfBith = new DateTime(1850, 12, 25)
Address = {
Address1 = "41 av 8 Mai 1945"
Address2 = None
City = "Sarcelles"
State = None
Zip = "95200"
}
PhoneNumber = {
DialOutCode = 33
LocalNumber = "766030703"
}
Email = "marcel.patulacci#outlook.com"
}
[<Fact>]
let ``Open an account...``() =
let event = Event.AccountOpened({
AccountId = id
Contact = contact
})
let a = [event]
let b = seq { yield event }
Assert.Equal(a, b)
The thing is when running the test independently the id and contact are not initialized, hence even though event was not null, contact was null (id being a Guid aka a struct it has a value anyway).
Since F# works with structural equality, if one of the field is not initialized it was enough to have a field null to make the Assert failed at some point in its implementation.
There are a few solutions / workarounds:
Defining those variables directly in the unit test body.
Defining methods which produce those values out of the unit test body
let getId() = Guid.Empty
let getContact() = {
Name = {
FirstName = "Marcel"
MiddleInitial = None
LastName = "Patulacci"
}
DateOfBith = new DateTime(1850, 12, 25)
Address = {
Address1 = "41 av 8 Mai 1945"
Address2 = None
City = "Sarcelles"
State = None
Zip = "95200"
}
PhoneNumber = {
DialOutCode = 33
LocalNumber = "766030703"
}
Email = "marcel.patulacci#outlook.com"
}
[<Fact>]
let ``Open an account...``() =
let id = getId()
let contact = getContact()
let event = Event.AccountOpened({
AccountId = id
Contact = contact
})
let a = [event]
let b = seq { yield event }
Assert.Equal(a, b)
While those workarounds work, I am surprised that the variables declared right above the unit test function are not considered when the test is running / and are uninitialized.
It might worth to shoot another question about why this is the case.
This is surprising in the sense that if a function can be defined and returning pretty much the same thing as those variables it means that let is also properly compiled, so why this is not the case with the variables?

Passing a function as a parameter in injecting data into SQL Server

I wrote a GetLoan function:
private void GetLoan(RadioButton radiobutton)
{
if(radiobutton.Checked)
{
MessageBox.Show(radiobutton.Text);
}
}
and in order to get the necessary data from the radio button I did this,
bookCom = new SqlCommand("UPDATE d_Book SET ISBN = #isbn, Author = #author, Title = #title, Publisher = #publisher, Date = #date, Loan = #loan WHERE ISBN = #isbn ", bookCon);
String ISBN = textISBN.Text;
String Author = textAuthor.Text;
String Title = textTitle.Text;
String Publisher = textPublisher.Text;
String Date = textDate.Text;
GetLoan(rdbtn_Yes); // worked fine
GetLoan(rdbtn_No); // worked fine
bookCom.Connection = bookCon;
bookCon.Open();
if (bookCon.State == ConnectionState.Open)
{
bookCom.Parameters.AddWithValue("#isbn", ISBN);
bookCom.Parameters.AddWithValue("#author", Author);
bookCom.Parameters.AddWithValue("#title", Title);
bookCom.Parameters.AddWithValue("#publisher", Publisher);
bookCom.Parameters.AddWithValue("#date", Date);
bookCom.Parameters.Add("#loan", SqlDbType.Char).Value = GetLoan; // didn't work at all
}
Is there any way I could get GetLoan to work?
You have to specify the return type in the function:
private string GetLoan(RadioButton radiobutton)
{
if (radiobutton.Checked)
{
return "yes";
}
else
{
return "no";
}
}
Or as a bool in one line of code:
private bool GetLoan(RadioButton radiobutton)
{
return radiobutton.Checked;
}
And then you always need to pass RadioButton as a parameter. So change
bookCom.Parameters.Add("#loan", SqlDbType.Char).Value = GetLoan;
To
bookCom.Parameters.Add("#loan", SqlDbType.Char).Value = GetLoan(rdbtn_Yes);
But why not make it easier and just check which one is selected:
String Loan = "no";
if (rdbtn_Yes.Checked == true)
{
Loan = "yes";
}
bookCom.Parameters.Add("#loan", SqlDbType.Char).Value = Loan;
By reading the snippet provided, I understand that you need to ask user if he/she is interested in loan.
Instead of radio buttons for yes or no, you could consider using a check box then use the below function.
private string GetLoan(CheckBox chkBxGetLoan)
{
//returns string value as output.
return chkBxGetLoan.Checked ? "Y" : "N";
}
OR
private char GetLoan(CheckBox chkBxGetLoan)
{
//returns char value as output.
return chkBxGetLoan.Checked ? 'Y' : 'N';
}

How to get value from Dictionary to new Object in LINQ query

I have a Collection of Data and the Dictionary:
Collection handle Student Data
Dictionary Keeps Student Courses.
I want to get the Course Name from the Dictionary and put it into as CourseName.
private viod GenerateStudentDetails(Student studentData)
{
var courses = m_courses.GetCoursesDictionary(); // returns Dictionary<Guid,string>()
var studentDetails= from data in studentData
select new
{
FirstName = data.FirstName,
LastName = data.LastName,
Email = data.Email,
Mobile = data.Profile.Mobile,
City = data.Profile.City,
PostCode = data.Profile.PostCode,
CourseName = courses[data.Profile.CourseID ?? Guid.Empty]
};
}
"LINQ to Entities does not recognize the method 'System.String get_Item(System.Guid)' method, and this method cannot be translated into a store expression."
You could try something as the below:
private viod GenerateStudentDetails(Student studentData)
{
var courses = m_courses.GetCoursesDictionary(); // returns Dictionary<Guid,string>()
var studentDetails= (from data in studentData
select new
{
FirstName = data.FirstName,
LastName = data.LastName,
Email = data.Email,
Mobile = data.Profile.Mobile,
City = data.Profile.City,
PostCode = data.Profile.PostCode,
CourseID = data.Profile.CourseID
}).AsEnumerable()
.Select(item=>new
{
FirstName = item.FirstName,
LastName = item.LastName,
Email = item.Email,
Mobile = item.Profile.Mobile,
City = item.Profile.City,
PostCode = item.Profile.PostCode,
CourseName = courses[item.Profile.CourseID ?? Guid.Empty]
});
}
What's the problem?
The problem is that the last expression in the anonymous type you create,
CourseName = courses[data.Profile.CourseID ?? Guid.Empty]
cannot be in this place, because it can't be translated appropriately. So you have this option. You can declare a sequence of the data you want from the studentData and then make any conversion of call anything you want to the new anonymous type we create.
Just for thought
var eCourses = ((IEnumerable<KeyValuePair<Guid, string>>) courses);
var studentDetails = (from data in studentData
select new
{
data.FirstName,
data.LastName,
data.Email,
data.Profile.Mobile,
data.Profile.City,
data.Profile.PostCode,
CourseName = eCourses.FirstOrDefault(s => s.Key == data.Profile.CourseID).Value
});

Adding a new case comment via Salesforce API C#

I'm working with the Salesforce Enterprise WSDL to manage Salesforce cases on a custom built C# web application. I've successfully been able to update the case owner however I can't figure out how to add a comment to the case. My code for updating the case owner is below. How do I add a new case comment?
public void UpdateCase(SalesforceLogin currentLogin, String caseId, String userId, String newComment)
{
sfdcBinding.Url = currentLogin.ServerUrl;
sfdcBinding.SessionHeaderValue = new SessionHeader();
sfdcBinding.SessionHeaderValue.sessionId = currentLogin.SessionId;
String query = "SELECT ID FROM Case WHERE CaseNumber = '" + caseId + "'";
QueryResult results = sfdcBinding.query(query);
if (results.records != null && !userId.IsNullOrEmpty())
{
SFDC.Case sfCase = results.records.Cast<SFDC.Case>().First();
if (!sfCase.Id.IsNullOrEmpty())
{
sfCase.OwnerId = userId;
SFDC.sObject[] toUpdate = new SFDC.sObject[1];
toUpdate[0] = sfCase;
sfdcBinding.update(toUpdate);
}
}
}
UPDATE: Code I'm using to add comments
public void AddCaseComment(SalesforceLogin currentLogin, String caseId, String userId)
{
sfdcBinding.Url = currentLogin.ServerUrl;
sfdcBinding.SessionHeaderValue = new SessionHeader();
sfdcBinding.SessionHeaderValue.sessionId = currentLogin.SessionId;
try
{
String query = "SELECT ID FROM Case WHERE CaseNumber = '" + caseId + "'";
QueryResult results = sfdcBinding.query(query);
if (results.records != null && !userId.IsNullOrEmpty())
{
SFDC.Case sfCase = results.records.Cast<SFDC.Case>().First();
if (!sfCase.Id.IsNullOrEmpty())
{
CaseComment caseComment = new CaseComment()
{
CommentBody = "test",
ParentId = sfCase.Id,
CreatedById = userId,
IsPublished = true,
LastModifiedById = userId
};
SFDC.sObject[] toCreate = new SFDC.sObject[1];
toCreate[0] = caseComment;
sfdcBinding.create(toCreate);
}
}
}
}
You will need to use the separate CaseComment object with the ParentId set to the target cases Id.

Categories