IQueryable fills null values with other values - c#

Here is what I want to do : Get a List of Batch Objects in my controller that I can send to the view and display it. It's working but the values are mixed up. If the value in the database is null or 0, the query fills it with another non-null value in the record. Here's an example.
Database Content
Id:13
TotalRequest : 10
TotalProcessed :0
CreatedDateTime:2017-01-13 13:30:46.090
CreatedBy:Test
CompletionDateTime : NULL
Iqueryable at position 13 content
Id:13
TotalRequest : 10
TotalProcessed :10
CreatedDateTime:2017-01-13 13:30:46.090
CreatedBy:Test
CompletionDateTime : NULL
You can see that the TotalProcessed is not correct. Also if I have a CompletionDateTime that is not null in one of the objects, the List doesn't care and always outputs null
The code:
IQueryable<Batch> IBatchList = context.batch.OrderByDescending(b => b.CreatedDateTime);
var batchList = IBatchList.ToList();
Batch Class(code first DB, so it's the definition of the DB as well)
public class Batch
{
[Key]
public Int64 Id { get; set; }
public int TotalRequested { get; set; }
public int TotalProcessed { get; set; }
public DateTime CreatedDateTime { get; set; }
public string CreatedBy { get; set; }
public DateTime? CompletedDateTime { get; set; }
}
Id TotalRequested TotalProcessed CreatedDateTime CreatedBy CompletedDateTime
13 10 0 2017-01-13 13:30:46.090 Test NULL
Here's the query from the Iqueryable :
{SELECT
[Extent1].[Id] AS [Id],
[Extent1].[TotalRequested] AS [TotalRequested],
[Extent1].[TotalProcessed] AS [TotalProcessed],
[Extent1].[CreatedDateTime] AS [CreatedDateTime],
[Extent1].[CreatedBy] AS [CreatedBy],
[Extent1].[CompletedDateTime] AS [CompletedDateTime]
FROM [dbo].[Batch] AS [Extent1]
ORDER BY [Extent1].[CreatedDateTime] DESC}

I solved the problem, I don't know why it repairs it, but I added a where statement to the query(CreatedDateTime is never null by the way, so I'll alway return all my records) and now I have all the correct data.
IEnumerable<BatchCode> IBatchCodeList = identityContext.BatchCodes.OrderByDescending(bc => bc.CreatedDateTime).Where(bc=>bc.CreatedDateTime != null);

Related

Code sending double value, EF creating query with it the wrong way

I'm filling up an object that has a double. In the database this field is a float. My EF savechanges fails as it says it returns 0 records.
I have used sql profiler to see which query it sends to the database, and this query indeed fails, thus causing it to return 0 records.
So EF is right, but it send my float into a query in a way that makes the query crash. Anyone has any idea why it does this? How I can avoid it?
This is my code object:
public partial class Rate : IRate
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
[Column(Order = 0)]
public int Id { get; set; }
[StringLength(3)]
public string source_currency { get; set; }
[StringLength(3)]
public string target_currency { get; set; }
public DateTime? date_l { get; set; }
public double? rate_exchange { get; set; }
[Key]
[Column(Order = 1)]
public DateTime CreatedOn { get; set; }
}
I put the double value into the rate_Exchange field in c# which works perfectly. Upon inspecting the element using debugger it has the correct double value in there.
However EF sends it to the database formatted like this:
exec sp_executesql N'INSERT [dbo].[Rates]([CreatedOn], [source_currency], [target_currency], [date_l], [rate_exchange])
VALUES (#0, #1, #2, #3, #4)
SELECT [Id]
FROM [dbo].[Rates]
WHERE ##ROWCOUNT > 0 AND [Id] = scope_identity() AND [CreatedOn] = #0',N'#0 datetime2(7),#1 varchar(3),#2 varchar(3),#3 datetime2(7),#4 float',#0='2023-02-08 15:58:58.0231618',#1='RUB',#2='EUR',#3='2023-02-01 00:00:00',#4=0,0132374518222941
obviously this fails cause it used a , instead of a . for the 4th parameter
any clues anyone?

SQL store procedure executes in SQL but not in code

I need your help. I have a store procedure that executes perfectly in SQL but when I call her from an IActionResult from a .net controller with FromSqlRaw(), returns the following error :
System.InvalidOperationException: 'The required column 'SeasonGroupClientCode' was not present in the results of a 'FromSql' operation.'
in Action:
var sql = "EXECUTE sp_seasonDataGroupedHorizonatlallyByCompany";
var list = _context.SeasonGroupedByCompanies.FromSqlRaw(sql).AsNoTracking().ToList();
Store Procedure:
select * from
(SELECT [SeasonGroupSeasonDescription] AS FirstSeason,[SeasonGroupClientCode] AS
FirstSeasonClientCode,[SeasonGroupClientName] AS
FistSeasonClientName,SeasonGroupCompanyId],
SUM([SeasonGroupStartValue]) AS FiSTotalStartValue ,
SUM([SeasonGroupFinalValue]) AS FiSTotalFinalValue
FROM [dbo].[SeasonGroupedByCompanies]
WHERE [SeasonGroupSeasonDescription]='SS21'
GROUP BY [SeasonGroupClientCode],[SeasonGroupClientName],
[SeasonGroupSeasonDescription],[SeasonGroupCompanyId]) as td
full join
(SELECT [SeasonGroupSeasonDescription] AS SecondSeason,[SeasonGroupClientCode] AS
SecondSeasonClientCode,[SeasonGroupClientName] AS SecondSeasonClientName,
[SeasonGroupCompanyId] AS SecondId,
SUM([SeasonGroupStartValue]) AS SeSTotalStartValue ,
SUM([SeasonGroupFinalValue]) AS SeSTotalFinalValue
FROM [dbo].[SeasonGroupedByCompanies]
WHERE [SeasonGroupSeasonDescription]='FW21'
GROUP BY [SeasonGroupClientCode],[SeasonGroupClientName],[SeasonGroupSeasonDescription],
[SeasonGroupCompanyId]) as tf
on td.FistSeasonClientName = tf.SecondSeasonClientName
full join
(SELECT [SeasonGroupSeasonDescription] AS ThirdSeason,[SeasonGroupClientCode] AS
ThirdSeasonClientCode,[SeasonGroupClientName] AS ThirdSeasonClientName,
[SeasonGroupCompanyId] AS ThirdId,
SUM([SeasonGroupStartValue]) AS ThSTotalStartValue ,
SUM([SeasonGroupFinalValue]) AS ThSTotalFinalValue
FROM [dbo].[SeasonGroupedByCompanies]
WHERE [SeasonGroupSeasonDescription]='SS22'
GROUP BY [SeasonGroupClientCode],[SeasonGroupClientName],[SeasonGroupSeasonDescription],
[SeasonGroupCompanyId]) as ts
on td.FistSeasonClientName = ts.ThirdSeasonClientName
full join
(SELECT [SeasonGroupSeasonDescription] AS FourthSeason,[SeasonGroupClientCode]AS
FourthSeasonClientCode,[SeasonGroupClientName] AS FourthSeasonClientName,
[SeasonGroupCompanyId] AS FourthId,
SUM([SeasonGroupStartValue]) AS FoSTotalStartValue ,
SUM([SeasonGroupFinalValue]) AS FoSTtotalFinalValue
FROM [dbo].[SeasonGroupedByCompanies]
WHERE [SeasonGroupSeasonDescription]='FW22'
GROUP BY [SeasonGroupClientCode],[SeasonGroupClientName],[SeasonGroupSeasonDescription],
[SeasonGroupCompanyId]) as tx
on td.FistSeasonClientName = tx.FourthSeasonClientName
Entity
public class SeasonGroupByCompany
{
[Key]
public int SeasonGroupCompanyId { get; set; }
public string? SeasonGroupSeasonDescription { get; set; }
public string? SeasonGroupSalesman { get; set; }
public int SeasonGroupClientCode { get; set; }
public string? SeasonGroupClientName { get; set; }
public int SeasonGroupQuantity { get; set; }
public int SeasonGroupDiscount { get; set; }
public double SeasonGroupStartValue { get; set; }
public double SeasonGroupFinalValue { get; set; }
The same error comes up, even if I run the query directly from FromRawSql().
Thanks in advance, any help will be appreciated
It looks like in the SeasonGroupedByCompany entity you have a field named SeasonGroupClientCode, but in the SQL query you have renamed it into FirstSeasonClientCode:
...[SeasonGroupClientCode] AS FirstSeasonClientCode...
Either rename the field in the entity, or don't rename the column in SQL, because originally the naming looks to be consistent.

Dapper yielding different results

I have a table :
create table scheduled_task
(
scheduled_task_id serial primary key,
description varchar(255),
predicate varchar(10485760),
path varchar(255),
scheduled_task_type_id int references scheduled_task_type (scheduled_task_type_id)
);
My data object :
[Table("scheduled_task")]
public class DOScheduledTask
{
[Key]
[Column("scheduled_task_id")]
public long? ScheduledTaskId { get; set; }
[Column("description")]
public string Description { get; set;}
[Column("predicate")]
public string Predicate { get; set; }
[Column("path")]
public string Path { get; set; }
[Column("scheduled_task_type_id")]
public long? ScheduledTaskTypeId { get; set; }
}
I inserted one record into the table, that populates all fields.
I perform this in code :
var schedules = conn.Connection.Query<DOScheduledTask>("select * from scheduled_task ;");
var schedulesb = conn.Connection.GetList<DOScheduledTask>();
The first line yields a record, with everything but scheduled_task_id and scheduled_task_type_id are both null. For the second query, it is populated in full.
What am I doing wrong?
The problem is that the .Query and .GetList are from two different implementations; the one is from Dapper, and the other is from SimpleCRUD.
The solution was to create a custom mapper, due to the naming of the columns being different in code than in the DB.

Cannot insert the value NULL into column 'Id', table '; column does not allow nulls

I'm seeing a strange behavior from Entity Framework. I'm using code-first approach to define a One-To-Many relationship between two entities:
public class IncomingCheck : AuditedEntityBase
{
[Key]
public int Id { get; set; }
[Required]
public virtual CheckType Type { get; set; }
[Required]
public virtual Bank Bank { get; set; }
public string Branch { get; set; }
public virtual IList<IncomingCheckHistory> History { get; set; }
}
public class IncomingCheckHistory
{
[Key]
public int Id { get; set; }
public string LongDescription { get; set; }
}
And here's I I'm trying to add an item to the History:
using (var db = new CheckDataContext())
{
foreach (var check in SelectedItems)
{
var dbCheck = await db.IncomingChecks.FindAsync(check.Id);
var history = new IncomingCheckHistory()
{
LongDescription = "something",
};
dbCheck.History.Add(history);
await db.SaveChangesAsync(); //throws the exception
}
}
But it throws an exception saying that "Cannot insert the value NULL into column 'Id'". However I've always done it like this. The database is supposed to fill the Id column itself with a unique number.
What am I missing?
Update:
Using SSProfiler, I got the query that runs on the database. It's as follows:
exec sp_executesql N'INSERT [dbo].[IncomingCheckHistories]([LongDescription], [IncomingCheck_Id])
VALUES (#0, #1)
SELECT [Id]
FROM [dbo].[IncomingCheckHistories]
WHERE ##ROWCOUNT > 0 AND [Id] = scope_identity()',N'#0 nvarchar(max) ,#1 int',#0=N'Something',#1=1
Note that scope_identity() should be getting the Id itself, correct?
Shouldn't the Id be set as the Identity?
Like this:
public class IncomingCheckHistory
{
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int Id { get; set; }
[Key]
public string LongDescription { get; set; }
}
Hope that this is the solution to your problem!
Well for some strange reason the exact code worked after completely deleting the database and migrations and starting from scratch. I'm not sure why it wouldn't work without migrations. Also I had tried deleting the database before but at the time I was trying a little different code.
In any case the posted code/query should work. Also I checked the database and the columns to see if anything is different and it wasn't. I would appreciate if someone could shed some light on why it wasn't working and it is now.

Error in linq query when using average

I have two tables, picture and pictureratings in my database.
public partial class picture
{
public int idpicture { get; set; }
public int iduser { get; set; }
public string picTitle { get; set; }
public string picFilename { get; set; }
public System.DateTime pictime { get; set; }
public int nuditylevel { get; set; }
public int fakeslevel { get; set; }
// This property will hold the total accumulated/summed
// up rating of a picture
public int totalrating { get; set; }
}
public partial class pictureratings
{
public int idrating { get; set; }
public int idpictures { get; set; }
public int iduser { get; set; }
public System.DateTime iddatetime { get; set; }
public int iduserrateddby { get; set; }
public int rating { get; set; }
}
For every rating a new pictureratings row will be created. I want to group pictureratings table by the picture id and then count the likes. I want to show those likes in picture table in totalrating property.
So as per my now I am able to write the following code
var combo = from p in db.picturedetails
join l in db.picturelikes on p.idpictures equals l.idpictures into pl
select new LikesandPictureDetails
{
IdUserPic = p.iduser,
IdPicturess =p.idpictures,
Likes = p.likes,
NudityLevel = p.nuditylevel,
PicTitle = p.picTitle,
PicTime = p.pictime,
picFilename=p.picFilename,
Count=pl.Count(),
totalrating = pl.Average(c => c.likenumber) // This line is causing error
};
I am using web api to return query total. I am showing picture properties like iduser, picTitle, picFilename, pictime, nuditylevel and fakeslevel.
As per now every thing runs smooth, but when I add totalrating = pl.Average(c => c.likenumber) , I get an exception saying
The cast to value type 'Double' failed because the materialized value is null. Either the result type's generic parameter or the query must use a nullable type.
How to remove the error?
Maybe the problem is that pl has no records, try
replace
totalrating = pl.Average(c => c.likenumber) // This line is causing error
with
totalrating = pl.DefaulIfEmpty(0).Average(c => c.likenumber)
db.picturelikes.likenumber seems to be nullable? Can't find the property defined in your code though.
Anyways you can select all entries which are not null by putting
pl.Where(a=>a.likenumber != DBNull.Value /* or null whatever this is... */).Average...
If it is a nullable property:
pl.Where(a=>a.likenumber.HasValue).Average(a=>a.likenumber.Value)
:edit
I think .average returns a null-able decimal in this case. To assign it to your field, simply put
totalrating = pl.Average(c => c.likenumber)
Totalrating seems to be an int, eigther you'll loose some information by casting it down to an int, or you change the type to double...
The error appears to be that your DB has a column that can contain null values, yet your object has a non-nullable double type.
Does the query run if you select an anonymous type, instead of a concrete one?
ie. change this
select new LikesandPictureDetails
to
select new
If so, then you should change the type of a value in your target object to be nullable.

Categories

Resources