I have table tb_Orders (it empty), which have fields^
- order_id (int) (primary key)
- order_date nchar(30)
In my application, when client make order, requests the function:
private int GetNewOrderId()
{
int ord_id = 0;
if (db.tb_Orders.Max(x => x.order_id) != null)
{
int ord = db.tb_Orders.Max(x => x.order_id);
ord_id = ord + 1;
}
else
{
ord_id = 1;
};
return ord_id;
}
which get the new order id (+1 to max order in table).
Operator "if" must, when the table is still empty, get id = 1;
But the result - error (when I try to get id).
ERROR TEXT: "Error converting cast a value type "Int32", as materialize value is null."
Try casting your order_id to a nullable integer when making the Max call:
private int GetNewOrderId()
{
int nextOrderId = db.tb_Orders.Max(x => (int?)x.order_id) ?? 1;
return nextOrderId;
}
You will also notice that in my example there's only a single SQL query to the database whereas you were making 2: one in the if statement and another one inside.
It seems your order_id is Nullable<int>. Use the Value property to get it's value, and you can also perform the query before if statement and don't execute the query twice:
var max = db.tb_Orders.Max(x => x.order_id);
if(max != null)
{
int ord = max.Value;
ord_id = ord + 1;
}
Related
total amateur here! I am working on a bingo app where i have a 4 x 4 grid. Each row and each column has a bool property which indicates whether it's a completed line or not. So..
bool row1 = false,
bool row2 = false,
bool row3 = false,
bool row4 = false,
bool column1 = false,
bool column2 = false,
bool column3 = false,
bool column4 = false
If the user completes a row the property changes to 'true' - I've worked that bit out.
Now i want a 'completedRows' property which provides the count of rows that = true (and same for columns)
Is it possible to create a function that does this?
Not convenient, but definitely possible:
int get completedRowCount =>
(row1 ? 1 : 0) + (row2 ? 1 : 0) + (row3 ? 1 : 0) + (row4 ? 1 : 0);
Since you are using individual variables, you have to access those variables independently.
You could do something like:
int get completedRowCount =>
[row1, row2, row3, row4].where((b) => b).length;
but that's not any more general than the code above, and more wasteful in memory use.
If instead of using individual variables, you used lists of booleans, then you can more easily generalize to, say, more rows or columns.
Say, you had
List<bool> row = List.filled(4, false);
List<bool> column = List.filled(4, false);
then instead of row1 = true; you write row[1] = true;,
but you can then use:
int get completedRowCount => row.where((b) => b).length;
to get the completed count. Or:
int get completedRowCount {
var count = 0;
for (var value in row) {
if (value) count++;
}
return count;
}
I'd probably wrap everything up in a class, that would allow you to abstract over the row and column count. Something like:
class BingoGrid {
final List<bool> completedRows;
final List<bool> completedColumns;
// Other properties.
BingoGrid(int columns, int rows)
: completedRows = List<bool>.filled(rows, false),
completedColumns = List<bool>.filled(columns, false);
// ...
static bool _isTrue(bool b) => b;
int get completedRowCount => completedRows.where(_isTrue).length;
int get completedColumnCount => completedColumns.where(_isTrue).length;
}
I have a table.
create table tblCartItem(
pkCartItemId int primary key identity,
CartId int not null,
ProductId int not null,
Quantity int not null,
Price nvarchar(15)
)
and I want to perform sum opeartion on that like as
Select SUM(Price) from tblCartItem where CartId='107'
and I am trying to following code but its not working
ObjTempCart.CartTotal = (from c in db.tblCartItems where c.CartId == cartId select c.Price).Sum();
Any one help me to do this using Entity Framework.
I am using MVC 4 Razor.
May be You can use lambda Expression
var total=db.tblCartItems.Where(t=>t.CartId == cartId).Sum(i=>i.Price);
its working try this..
use Decimal.Parse to convert price.
ObjTempCart.CartTotal = db.tblCartItems.Where(t=>t.CartId == cartId).Select(i=>Decimal.Parse(i.Price)).Sum();
Finally I have a solution of that but its not exactly from Entity Framework, But its working...
private double CartItemTotalPrice(Int32 CartID)
{
List<string> pricelst = new List<string>();
pricelst = (from c in db.tblCartItems where c.CartId == CartID select c.Price).ToList();
double Total = 0;
if (pricelst != null)
{
for (int i = 0; i < pricelst.Count; i++)
{
Total += Convert.ToDouble(pricelst[i]);
}
}
return Total;
}
Decimal.parse not working, try Convert.toDouble
double total = _context.Projecao
.Where(p => p.Id == idProj)
.Select(i => Convert.ToDouble(i.ValorTotal)).Sum();
I'm using context.Database.ExecuteSql to update a table. The update with where clause is executed correctly and the record is updated. However the method returns 2 for rowcount instead of 1. When I execute the update statement in SSMS, the result rowcount returned is 1. Can someone provide insight on this?
string query =
string.Format("update {0} set Description = '{1}', Code = '{2}', LastUpdatedBy = '{3}', LastUpdatedDate = '{4}' where ID = {5};",
tableName,
description,
code,
lastUpdatedBy,
lastUpdatedDate,
ID);
int rowCount = 0;
string message = string.Empty;
using (DBContext context = new DBContext())
{
rowCount = context.Database.ExecuteSqlCommand(TransactionalBehavior.EnsureTransaction, query);
}
return rowCount == 0 ? //this return 2 instead of 1.
new SaveResult(SaveResult.MessageType.Error, string.Format("There was an error updating a record in the {0} table.", tableName), "Index") :
new SaveResult(SaveResult.MessageType.Success, string.Format("The update of {0} was successful.", tableName), "Index");
This returns rowcount = 1 in SSMS:
update zAddressTypes
set Description = 'Current', Code = '101122', LastUpdatedBy = 'user', LastUpdatedDate = '10/20/2014 12:17:26 PM'
where ID = 1;
DECLARE #RowCount INTEGER = ##ROWCOUNT;
select #RowCount;
The rowcount is being returned separately. What you are seeing here is the exit status of the query.
ExecuteSqlCommand return value is for the status of query not for row count. You may want to look into using a datareader or something similar to return the rowcount.
It is the way the datacontext works, see this link:
Entity Framework: Database.ExecuteSqlCommand Method
Apparently the command is updating two records.
Do you have a trigger on your table? I confirmed this behavior can be caused by a trigger as the rows affected by the trigger are added to the row count affected by your SQL command. I commonly check for a 0 or >0 return value to know if anything was affected. You could also return an output variable if you're calling a stored procedure.
I'm using EF DbContext SqlQuery to get a list of paged objects using PagedList (https://github.com/TroyGoode/PagedList) and I'm getting the following error:
"The SqlParameter is already contained by another SqlParameterCollection"
Here's my repository code:
var db = (DbContext)DataContext;
const string sqlString =
#"
WITH UserFollowerList
AS
(
SELECT uf.FollowId
FROM UserFollow uf
WHERE uf.UserId = #UserId
)
SELECT * FROM UserFollowerList uf
INNER JOIN [User] u ON uf.FollowId = u.UserId
WHERE IsDeleted = 0
"
;
var userIdParam = new SqlParameter("UserId", SqlDbType.Int) {Value = userId};
var userList =
db.Database.SqlQuery<User>(sqlString, userIdParam)
.ToPagedList(pageIndex, pageSize);
return userList;
But when I call the ToList extension on the SqlQuery statement it works fine:
var userList = db.Database.SqlQuery<User>(sqlString, userIdParam).ToList();
PagedList code:
private PagedList(IQueryable<T> source, int pageIndex, int pageSize)
{
TotalItemCount = source.Count();
PageSize = pageSize;
PageIndex = pageIndex;
PageCount = TotalItemCount > 0 ? (int)Math.Ceiling(TotalItemCount / (double)PageSize) : 0;
HasPreviousPage = (PageIndex > 0);
HasNextPage = (PageIndex < (PageCount - 1));
IsFirstPage = (PageIndex <= 0);
IsLastPage = (PageIndex >= (PageCount - 1));
ItemStart = PageIndex * PageSize + 1;
ItemEnd = Math.Min(PageIndex * PageSize + PageSize, TotalItemCount);
// add items to internal list
if (TotalItemCount > 0)
Data = pageIndex == 0 ? source.Take(pageSize).ToList() : source.Skip((pageIndex) * pageSize).Take(pageSize).ToList();
}
I've already the solution below without any success:
var param = new DbParameter[] { new SqlParameter { ParameterName = "UserId", Value = userId }
What can I do to fix the error I'm experiencing?
FYI I just saw this exact same error message when using an EF 5 DbContext to call context.ExecuteQuery<my_type>(...); with an array of SqlParameters, where my_type had a string but the SQL statement was returning an int for one of the parameters.
The error was really in the return mapping, but it said the SqlParameter was to blame, which threw me off for a little while.
When using a generic call to SqlQuery such as db.Database.SqlQuery you must iterate to the last record of the returned Set in order for the result set and associated parameters to be released. PagedList uses source.Take(pageSize).ToList() which will not read to the end of the source set. You could work around this by doing something like foreach(User x in userList) prior to returning the result.
I tried the following solution from Diego Vega at http://blogs.msdn.com/b/diego/archive/2012/01/10/how-to-execute-stored-procedures-sqlquery-in-the-dbcontext-api.aspx and it worked for me:
var person = context.Database.SqlQuery<Person>(
"SELECT * FROM dbo.People WHERE Id = {0}", id);
When you are using parameters on (SqlQuery or ExecuteSqlCommand) you can't use theme by another query until old query dispose.
in PagedList method you use "source.Count();" at first and the end line you are using "source" again. that's not correct.
you have 2 solution.
1- send param to PagedList Method and new theme for each using SqlQuery or ExecuteSqlCommand
2-remove PagedList and send your paging param to SqlQuery or ExecuteSqlCommand like this :
const string sqlString =
#"
WITH UserFollowerList
AS
(
SELECT uf.FollowId,ROW_NUMBER() OVER(ORDER BY uf.FollowId ) RowID
FROM UserFollow uf
WHERE uf.UserId = #UserId
)
SELECT * FROM UserFollowerList uf
INNER JOIN [User] u ON uf.FollowId = u.UserId
WHERE IsDeleted = 0 and RowID BETWEEN (((#PageNumber- 1) *#PageSize)+ 1) AND (#PageNumber * #PageSize))
"
;
Just encountered this exception even though it was my first query to the database with a single param. And having the Context in a 'using'.
When I 'hardcoded' the queryparameter valies into the string it worked correct for some reason. But as soon as I used SqlParameter it gave me the "The SqlParameter is already contained by another SqlParameterCollection"
This didn't work:
context.Database.SqlQuery<int?>(query, new SqlParameter("#TableName", tableName));
This did:
context.Database.SqlQuery<int>(query, new SqlParameter("#TableName", tableName));
The difference being the return type int? vs int. So for anyone reading this. Please also check your return type of the SqlQuery even when you're sure it should work.
This is old, but I ran into the same problem and someone has thought of the solution here
https://dotnetfiddle.net/GpEd95
Basically you need to split this up into a few steps in order to get your paged query
//step 1 set the page numbers
int pageNumber = 1;
int pageSize = 2;
//step 2 set your parameters up
var parm2 = new SqlParameter("param1", "Kevin");
var parm1 = new SqlParameter("param1", "Kevin");
var pageParm = new SqlParameter("#p2", (pageNumber - 1) * pageSize);
var pageSizeParm = new SqlParameter("#p3", pageSize);
//step 3 split your queries up into search and count
var sqlString = #"SELECT FT_TBL.*
FROM EquipmentMaintenances AS FT_TBL
INNER JOIN FREETEXTTABLE(vw_maintenanceSearch, Search, #param1) AS KEY_TBL ON FT_TBL.EquipmentMaintenanceID = KEY_TBL.[KEY]
WHERE FT_TBL.Status = 1
ORDER BY RANK DESC, FT_TBL.EquipmentMaintenanceID DESC OFFSET #p2 ROWS FETCH NEXT #p3 ROWS ONLY";
var sqlCountString = #"SELECT COUNT(1)
FROM EquipmentMaintenances AS FT_TBL
INNER JOIN FREETEXTTABLE(vw_maintenanceSearch, Search, #param1) AS KEY_TBL ON FT_TBL.EquipmentMaintenanceID = KEY_TBL.[KEY]
WHERE FT_TBL.Status = 1
";
//step 4 run your queries c# doesn't like the reusing of parameters so create 2 (e.g Kevin) so your results will run correctly.
var main = _db.Database.SqlQuery<EquipmentMaintenance>(sqlString, parm1, pageParm, pageSizeParm).ToList();
var count = _db.Database.SqlQuery<int>(sqlCountString, parm2).FirstOrDefault();
//step 5 created your paged object - I'm using x.pagedlist
var paged = new StaticPagedList<EquipmentMaintenance>(main, pageNumber, pageSize, count);
Obviously your now passing this back to your view or other function for display.
I have URL: http://site.com/page.aspx?update
how do I check if that update value is present?
HttpValueCollection treats that as an entity with null key. I have tried:
var noKeyValues = Request.QueryString.GetValues(null);
if (noKeyValues != null && noKeyValues.Any(v=>v==update)) ...
but it gives me a frowny line, because GetValues' argument is decorated with [NotNull].
so I end up doing:
var queryValuesWithNoKey =
Request.QueryString.AllKeys.Select((key, index) => new { key, value = Request.QueryString.GetValues(index) }).Where(
item => item.key == null).Select(item => item.value).SingleOrDefault();
if (queryValuesWithNoKey != null && queryValuesWithNoKey.Any(v => v.ToLower() == "update")) live = true;
not the most elegant workaround. Is there a better way to get key-less value from query string?
You can use
Request.QueryString[null]
to retrieve a comma separated list of keys with no values. For instance, if your url is:
http://mysite/?first&second
then the above will return
first,second
In your case, you could just do something like:
if(Request.QueryString[null] == "update")
{
// it's an update
}
if that's the only key you would use
Request.QueryString.ToString() to get the "update" value
I know I'm late to the party, but this a function that I use for this kind of task.
internal static bool HasQueryStringKey(HttpRequestBase request, string key)
{
// If there isn't a value, ASP will not recognize variable / key names.
string[] qsParts = request.QueryString.ToString().Split('&');
int qsLen = qsParts.Length;
for (int i = 0; i < qsLen; i++)
{
string[] bits = qsParts[i].Split('=');
if (bits[0].Equals(key, StringComparison.OrdinalIgnoreCase))
{
return true;
}
}
return false;
}
You may need to update it so that it is case sensitive, or uses different arguments depending on your purposes, but this has always worked well for me.