On my ASP.NET MVC4 application, I need a dropdown-list to select a Location and insert its ID into a table, say News.
Some news apply to ALL Locations - therefore the LocationID in News is Nullable, to indicate this.
So I need to add "ALL Locations" to the dropdown.
This is how I imagined, it would work - but on the last line Value = DBNull.Value (or simple null) is not allowed. It only accepts an integer. I CANNOT use "0" as foreign key constraints on that table do not allow 0, because there is no ID=0 in Locations-table
var locations = db.Locations.Select(c => new { DisplayText = c.Location, Value = c.ID }).ToList();
locations.Insert(0, new { DisplayText = "All Locations", Value = DBNull.Value });
return Json(new { Result = "OK", Options = locations});
How can I add this to the options-list?
The basis of your locations anonymous object is created in the new {} operator in your Linq statement. If you need to allow for NULL, then... new { DisplayText = c.Location, Value = (int?)c.ID } explicitly set the anonymous type's Value parameter as nullable int. Then you can do Value = null on the next line when inserting.
Related
So I made a windows form which has a search textbox that will return the parts of string that you have entered in the datagrid. However, in my attempt to code this following event. The datagrid shows boolean instead.
Which parts of the code is making all these result turns boolean and how can i fix this?
private void txtSearch_TextChanged(object sender, EventArgs e)
{
this.dataGridView1.DataSource = null;
this.dataGridView1.Rows.Clear();
using (var context = new edeappEntities1())
{
var data = context.bookingorders
.Join(
context.addressbooks,
booking => booking.addrID,
address => address.addrID,
(booking, address) => new
{
accID = booking.accID.Contains(txtSearch.Text),
bookId = booking.bookingID.Contains(txtSearch.Text),
companyName = address.companyName.Contains(txtSearch.Text),
address = address.addressLn1.Contains(txtSearch.Text) || address.addressLn2.Contains(txtSearch.Text) ||
address.addressLn3.Contains(txtSearch.Text),
region = address.region.Contains(txtSearch.Text),
postcode = address.postcode.Contains(txtSearch.Text),
contact = address.contectName.Contains(txtSearch.Text),
phone = address.phoneNo.Contains(txtSearch.Text),
fax = address.faxNo.Contains(txtSearch.Text),
telex = address.telexNo.Contains(txtSearch.Text),
pickupTime = booking.pickupDate.Contains(txtSearch.Text)
|| booking.pickupTime.Contains(txtSearch.Text)
}
).ToList();
foreach (var db in data)
{
dataGridView1.Rows.Add(db.accID, db.bookId, db.companyName, db.address, db.region,
db.postcode, db.contact, db.phone, db.fax, db.telex, db.pickupTime);
}
}
}
My modelling structure: model1.edmx
Search result is boolean: link
You are getting a Boolean result in all the columns because you are creating a new anonymous type and assigning the result of string.Contains() method to each property in that new anonymous type and string.Contains() returns a Boolean(bool).
For example, if I do this:
string str = "Hello!"
bool result = str.Contains("o");
Here, the Contains() method will return a Boolean value indicating whether the string contains the specified substring("o") in it. The return value here will be true which will be assigned to result.
In your code, you do something similar for each field:
accID = booking.accID.Contains(txtSearch.Text)
This will check if booking.accID contains the string searched by the user which is captured in txtSearch.Text. If your booking.accID contains txtSearch.Text, the method will return true and false if it does not contain the search text. This will create a new variable of type bool called accId and the return value will be stored in accId on the left-hand side of =.
Anonymous Types
In C#, an anonymous type is a quick way to create a wrapper object containing a set of properties without actually creating a class.
For instance, I want an object containing details about a person without creating a Person class, I can do this:
var myPerson = new { Name = "John", Age = 25, Salary = 10_000L };
Now, I have an object containing the properties Name, Age and Salary without even creating a Person class. The compiler creates a hidden class in the background. More on anonymous types here.
You are creating a lambda function that returns an anonymous type as the fourth parameter of the Join() method. This lambda function will be called on each result of the join operation.
Solution
The filtering condition should be specified in a Where() method instead of assigning it to properties in the anonymous type. The anonymous type should be used to capture and combine the two results:
var searchData = context
.bookingorders
.Join(
context.addressbooks,
booking => booking.addrID,
address => address.addrID,
(booking, address) => new
{
Booking = booking,
Address = address
})
.Where(data =>
data.Booking.bookingID.Contains(txtSearch.Text) ||
data.Address.companyName.Contains(txtSearch.Text) ||
data.Address.addressLn1.Contains(txtSearch.Text) ||
data.Address.addressLn2.Contains(txtSearch.Text) ||
data.Address.region.Contains(txtSearch.Text) ||
data.Address.postcode.Contains(txtSearch.Text) ||
data.Address.contectName.Contains(txtSearch.Text) ||
data.Address.phoneNo.Contains(txtSearch.Text) ||
data.Address.faxNo.Contains(txtSearch.Text) ||
data.Address.telexNo.Contains(txtSearch.Text) ||
data.Booking.pickupDate.Contains(txtSearch.Text) ||
data.Booking.pickupTime.Contains(txtSearch.Text)
)
.ToList();
foreach(var row in searchData)
{
dataGridView1.Rows.Add(
row.Booking.bookingId,
row.Address.companyName,
$"{row.Address.addressLn1} {row.Address.addressLn2}",
row.Address.region,
row.Address.postcode,
row.Address.contectName,
row.Address.phoneNo,
row.Address.faxNo,
row.Address.telexNo,
row.Booking.pickupDate,
row.Booking.pickupTime
);
}
The user must enter the name of the student and then enter the number of faults he has (the numFaltas column)
How do I change only the numFalts column and keep the rest?
Sorry for English. I'm learning yet.
Thank you!
My list:
alunosMatriculados.Add(new Aluno
{
matAluno = 1,
nomeAluno = "THIAGO BUARQUE",
cpfAluno = "111.111.111-11",
turmaAluno = "3H",
numFaltas = 4
});
alunosMatriculados.Add(new Aluno
{
matAluno = 2,
nomeAluno = "MARIANA DA SILVA",
cpfAluno = "111.111.111-12",
turmaAluno = "2I",
numFaltas = 0
});
You can do something like this:
if (alunosMatriculados.Any(a => a.nomeAluno == inputName))
alunosMatriculados.Where(a => a.nomeAluno == inputName).ToList().ForEach(a =>a.numFaltas = inputFaults);
But be careful because if there's more than one student with the same name you will change the faults for all of them. It would be better to make sure that the names are unique or use an unique field like an ID (maybe your matAluno)
You can do this in simple way by using foreach loop
You first verify that If your inputName parameter is null or not
Like
if (!String.IsNullOrEmpty(inputName))
{
foreach (Aluno a in alunosMatriculados)
if (a.nomeAluno == inputName)
a.numFaltas = inputValue;
}
in above code can comapre id also instead of inputName in inner if condition
By this way can only alter your numFaltas and any other also that you want
Here is the query:
using (var _context = GetCommonDataContext())
{
return await _context.AnswerSelectListEntries
.Include(asle => asle.Optional)
.OrderBy(asle => asle.DisplayOrder)
.Select(asle => new AnswerSelectListEntryDTO()
{
Id = asle.Id,
AnswerSelectListId = asle.AnswerSelectListId,
ShortAnswer = asle.ShortAnswer,
LongAnswer = asle.LongAnswer,
CounterpartyGroupId = asle.CounterpartyGroupId,
Optional = new AnswerDefDTO()
{
Id = asle.Optional.Id,
Name = asle.Optional.Name,
AnswerType = asle.Optional.AnswerType,
MultiplierAnswerType = asle.Optional.MultiplierAnswerType,
IntRangeLow = asle.Optional.IntRangeLow,
IntRangeHigh = asle.Optional.IntRangeHigh,
AnswerSelectListId = asle.Optional.AnswerSelectListId
},
AnswerDefId = asle.AnswerDefId,
PartyType = asle.PartyType,
DisplayOrder = asle.DisplayOrder
}).ToListAsync();
}
I am getting an error (thrown from the subquery) that Id, and AnswerType (which is an enum) cannot be cast to their counterparts (int and enum) because they are null. The issue is that they are non-nullable (and not null in the db). Somehow, asle.Optional's properties are being set to null (even though they are non-nullable). I am guessing this has something to do with the async but not sure what.
Fixed using:
Optional = asle.Optional == null ? null : new AnswerDefDTO()...
My guess would be that, since that thing is optional, and is making some kind of join, most likely a left join in the database, that the columns are coming back as DBNull simply because they weren't actually in the database. I would advise you to run a SELECT * FROM Optional where ID = whatever asle.Id is.
I use his code for executing SQL query in entity framework :
using (var db = new VSServicesEntities())
{
const string selectCmd = #"if exists (Select top 1 IsUserOn From ServiceMembers Where ServiceCode={0} and Number={1})
Select isnull(IsUserOn,0) IsUserOn
From ServiceMembers Where ServiceCode={0} and Number={1}
else
Select Null IsUserOn";
var data = db.ServiceMembers.SqlQuery(selectCmd, "A", 091242535970).ToList();
if (data.Any())
{
var serviceMember = data.First().IsUserOn;
if (serviceMember.ToString() == "")
label1.Text = "";
else
label1.Text = (serviceMember.ToString() == "True" ? "On" : "Off");
}
}
but it gives me an exception :
Must declare the scalar variable "#ServiceCode".
but i give value to ServiceCode= A , what is the problem?
EDIT 2: I edited my query on top, but now it gives me another exception :
The data reader is incompatible with the specified 'VSServicesModel.ServiceMember'. A member of the type, 'ServiceCode', does not have a corresponding column in the data reader with the same name
but my column name is exactly : ServiceCode!! what is the problem??
You aren't passing parameters correctly:
var data = db.ServiceMembers.SqlQuery(selectCmd,
new SqlParameter("#ServiceCode", "A"),
new SqlParameter("#Number", 091242535970)).ToList();
Edit
The type that EF will attempt to assign to data is the type of the element of ServiceMembers (assuming ServiceMember). The only field you return is IsON which does not match the property IsUserOn which you reference. Try instead:
Select isnull(IsUserOn,0) AS IsUserON
...
Select Null AS IsUserON
Note that other properties will not be populated unless you return them from the query with matching names.
Edit You've changed your sql query - the binding was working correctly with ServiceCode=#ServiceCode and Number=#Number. At a guess, the reason why the Reader is complaining is because you are returning just one column (IsUserON) and trying to bind it to your full ServiceMember class. Either return all the columns (especially the primary key, presumably ServiceCode), or alternatively create a new class just with the property IsUserON and then use the generic type overload db.SqlQuery<MyNewPoco>(cmd, ...) to bind it.
I read this article on ravendb set operations, but it didn't show me exactly how to update a set of documents via C#. I would like to update a field on all documents that match a certain criteria. Or to put it another way, I would like to take this C# and make it more efficient:
var session = db.GetSession();
foreach(var data in session.Query<Data>().Where(d => d.Color == "Red"))
{
data.Color = "Green";
session.Store(data);
}
session.SaveChanges();
See http://ravendb.net/docs/2.5/faq/denormalized-updates
First parameter is the name of the index you wish to update.
Second parameter is the index query which lets you specify your where clause. The syntax for the query is the lucene syntax (http://lucene.apache.org/java/2_4_0/queryparsersyntax.html). Third parameter is the update clause. Fourth parameter is if you want stale results.
documentStore.DatabaseCommands.UpdateByIndex("DataByColor",
new IndexQuery
{
Query = "Color:red"
}, new[]
{
new PatchRequest
{
Type = PatchCommandType.Set,
Name = "Color",
Value = "Green"
}
},
allowStale: false);