I am using CTE with PetaPOCO and getting a strange error
SQL Exception: Invalid Object Name PayTransactionForRollingVacationAverage that references the model that the data should map to.
The code is as follows.
public IEnumerable<PayTransactionForRollingVacationAverage> GetPayTransactionForRollingVacationAverage(DateTime payEndingDate)
{
PointsNorth.PetaPoco.Sql sql = new PointsNorth.PetaPoco.Sql();
sql.Append(#"
;with HolidayWeeks as
(
Select Distinct EmployeeId, PayEndDate, 'Y' as HolidayWeek
from PayTransactions
where PayEndDate = #payEndingDate
and LaborCode in ('251', '249')
)", new { payEndingDate });
sql.Append(#"
Select
PT.EmployeeId,
PT.PayEndDate,
J.JobClass,
PayCodes.AverageRateCode,
PT.RegularHours,
PT.RegularRate,
PT.RegularAmount
from PayTransactions PT
Left Outer Join PayCodes on PayCodes.PayCodeCode = PT.LaborCode
Left Outer Join HolidayWeeks as H on H.PayEndDate = PT.PayEndDate and H.EmployeeId = PT.EmployeeId
Inner Join Jobs as J on J.JobId = PT.JobId
where PT.PayEndDate = #payEndingDate
and IsNull(H.HolidayWeek, 'N') <> 'Y'
order by PT.EmployeeId, PT.PayEndDate, J.JobClass", new { payEndingDate });
var data = Database.Query<PayTransactionForRollingVacationAverage>(sql);
return data;
}
The model is pretty simple:
public class PayTransactionForRollingVacationAverage
{
public long EmployeeId { get; set; }
public DateTime PayEndDate { get; set; }
public string JobClass { get; set; }
public string AverageRateCode { get; set; }
public decimal RegularHours { get; set; }
public decimal RegularRate { get; set; }
public decimal RegularAmount { get; set; }
}
I tried breaking the SQL up to make sure it was building correctly, but I still get the error. Any idea why this is occurring?
Remove the whitespace before the semi-colon.
According to Alex Jorgenson's link, this is fixed if you make a semi-colon the very first character.
According to my testing, this is strictly the first character, i.e. if there is even some whitespace before the semi-colon, the auto-generated code will still be spit out.
This is a known issue with Peta Poco. It appears to be fixed in some version but I don't know which one. You can find more information and a work around for this particular issue at https://github.com/toptensoftware/PetaPoco/issues/22
Related
Hello I am new to apex and soql, I would like some help on my test class, below is the code i am having trouble with,
public class UpdateMyCard {
#AuraEnabled(cacheable=false)
public static Card__c updateCard(Double Amount){
String userId = UserInfo.getUserId();
Card__c myCard = [SELECT Id, Card_no__c, total_spend__c From Card__c Where OwnerId =:userId];
myCard.total_spend__c = myCard.total_spend__c + Amount;
try{
update myCard;
}catch (Exception e) {
System.debug('unable to update the record due to'+e.getMessage());
}
return myCard;
}
}
Test Class
#isTest
public static void updatecard(){
UpdateMyCard.updateCard(200);
}
Error:
System.QueryException: List has no rows for assignment to SObject
Your code assumes there's already a Card record for this user. And it's exactly 1 record (if you have 2 your query will fail). I'm not sure what's your business requirement. Is it guaranteed there will always be such record? Should the code try to create one on the fly if none found? You might have to make that "updateCard" bit more error-resistant. Is the total spend field marked as required? Because "null + 5 = exception"
But anyway - to fix your problem you need something like that in the test.
#isTest
public static void updatecard(){
Card__c = new Card__c(total_spend__c = 100);
insert c;
UpdateMyCard.updateCard(200);
c = [SELECT total_spend__c FROM Card__c WHERE Id = :c.Id];
System.assertEquals(300, c.total_spend__c);
}
I am trying to put in validation for the mobile number entered by the user despite putting in regular expression for 10 digit mobile number.
Here is the Model class
public partial class student1
{
public int StudentId { get; set; }
[Required]
[StringLength(30)]
public string Name { get; set; }
public string Branch { get; set; }
[Display(Name = "Mobile Number:")]
[Required(ErrorMessage = "Mobile Number is required.")]
[RegularExpression("^([07][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9] | 8[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9] | 9[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9])", ErrorMessage = "Invalid Mobile Number.")]
public Nullable<int> Mobile { get; set; }
}
Create view
#Html.EditorFor(model => model.Mobile)
#Html.ValidationMessageFor(model => model.Mobile, "", new { #class = "text-danger" })
When I run it, for mobile number entered less than 10 it shows the error message that I had written. But for value 10 and greater I get a new message that says
The value '999999999' is not valid for Mobile Number:.
I don't know where is this message coming from. Also, why isn't it accepting the 10 digit value?
Maximum value for int in c# for 64 bit machine is
2,147,483,647
which is less than 9999999999 so it is overflow for int, so it is error message for model validation from Controller before model binding.
Convert int to long
public Nullable<long> Mobile { get; set; }
Also check regular expression, it might miss some valid numbers too.
int max value for c# source:
https://msdn.microsoft.com/en-us/library/system.int32.maxvalue(v=vs.110).aspx
What is the int.MaxValue on a 64-bit PC?
try Regular Expression = ^(\d{1,3}[- ]?)?\d{10}$
I have a result from a database query that is:
IEnumerable<ResultRecord> results_from_db_call = Db.GoGetItNow();
Now lets assume the returned class looks like:
public class ResultsRecord
{
public string DataBlob { get; set; }
public int FirstID { get; set; }
public int SecondNum { get; set; }
public DateTime ThirdDate { get; set; }
public string FourthTime { get; set; }
public string FifthTime { get; set; }
}
Now, the result records returned only have the DataBlob member set
It very well might look like:
<IK/12322>1354654 16/MAY/2014 18:01:01 - 20:01:01
So, I need to fill the other members, and would like to do so with an 'Each' delegate:
results.Each(f => f.FirstID = int.Parse(Regex.Match(f.DataBlob, #"\d+").Value));
results.Each(f => f.SecondNum = int.Parse(Regex.Match(f.DataBlob, #"\d+").Value));
results.Each(f => f.ThirdDate = DateTime.Parse(Regex.Match(f.DataBlob, #"\d+").Value));
results.Each(f => f.FourthTime = Regex.Match(f.DataBlob, #"\d+").Value));
results.Each(f => f.FifthTime = Regex.Match(f.DataBlob, #"\d+").Value));
Well, as you can imagine, that regex expression only worked on the first integer..
But wait! I have a working Regex to find all the groups I need:
(\d+)\>(\d+) (\d+\/[a-zA-Z]+\/\d+) (\d+\:\d+\:\d+) - (\d+\:\d+\:\d+)
This successfully groups all items that I need.
But, and here's the question, how do I get the second regex group item for SecondNum, the third regex group item for ThirdDate, the fourth regex group item for FourthTime, and the fifth regex group item for FifthTime?
When I try
(\d+)\>(\d+) (\d+\/[a-zA-Z]+\/\d+) (\d+\:\d+\:\d+) - (\d+\:\d+\:\d+){0}
I don't get the first (zeroth) item.
How can I call the regex to get the first, etc item from the groupings?
results.Each(f => f.SecondNum = int.Parse(Regex.Match(f.DataBlob, #"????").Value));
You should parse the whole string first so that you will be able to capture different groups:
string pattern = #"(\d+)\>(\d+) (\d+\/[a-zA-Z]+\/\d+) (\d+\:\d+\:\d+) - (\d+\:\d+\:\d+)";
Match m = Regex.Match(f.DataBlob, pattern);
// You can then refer to the matched group this way:
// m.Groups[1] = 12322
// m.Groups[2] = 1354654
// ...etc
Group g = m.Groups[2];
// Then parse into integer
Do note that capture group starts from 1, instead of 0. You can also take a look at the example here.
I have written an ASP.NET web service.
It looks like this:
WebServices.logic pLogic = new WebServices.logic();
WebServices.manager[] pManager = new PowerManager[1];
pManager[0] = new PowerManager();
pManager[0].CustomerId = "sjsjshd";
pManager[0].state = pLogic.getState("sasj");
return pManager[0];
The pManager class looks like this:
public string _CustomerId;
public int PowerStatus;
public List<ArrayList> _Power;
public string CustomerId
{
get
{
return _CustomerId;
}
set
{
_CustomerId = value;
}
}
public List<ArrayList> Power
{
get
{
return _Power;
}
set
{
_Power = value;
}
}
When I run it, I get a repetition of the results, like so:
<p>
<_CustomerId>sjsjshd</_CustomerId>
<pStatus>0</PowerStatus>
−
<_p>
−
<ArrayOfAnyType>
<anyType xsi:type="xsd:int">1</anyType>
</ArrayOfAnyType>
<ArrayOfAnyType/>
</_p>
<CustomerId>sjsjshd</CustomerId>
−
<p>
−
<ArrayOfAnyType>
<anyType xsi:type="xsd:int">1</anyType>
</ArrayOfAnyType>
<ArrayOfAnyType/>
</p>
</pManager>
However, there is no duplicate values stored (Eg. I store client name in a collection, but only once - count of 1). There are no duplicates stored when I call getState(). This method returns a collection and it contains one value, but the results in XML has a repetition of this.
How comes the results appear to repeat themselves? When running the system, I only get one error.
Thanks
OK, looks like your XML serialization is giving you all the public members of your PowerManager class. Based on the naming convention of starting with an underscore, those members should be private, like this:
private string _CustomerId;
private List<ArrayList> _Power;
You also state "When running the system, I only get one error." What error are you getting?
Using NUnit 2.2 on .NET 3.5, the following test fails when using DateTime.Equals. Why?
[TestFixture]
public class AttributeValueModelTest
{
public class HasDate
{
public DateTime? DateValue
{
get
{
DateTime value;
return DateTime.TryParse(ObjectValue.ToString(), out value) ? value : new DateTime?();
}
}
public object ObjectValue { get; set; }
}
[Test]
public void TwoDates()
{
DateTime actual = DateTime.Now;
var date = new HasDate {ObjectValue = actual};
Assert.IsTrue(date.DateValue.Value.Equals(actual));
}
}
The dates aren't equal. TryParse drops some ticks. Compare the Tick values.
For one test run:
Console.WriteLine(date.DateValue.Value.Ticks);
Console.WriteLine(actual.Ticks);
Yields:
633646934930000000
633646934936763185
The problem isn't really TryParse, but actually ToString().
A DateTime object starts with precision (if not accuracy) down to millionth of seconds. ToString() convertsit into a string, with precision only to a second.
TryParse is doing the best it can with what it is given.
If you add a format specifier (along the lines of "yyyy-MM-dd HH:mm:ss.ffffff"), it should work.
To specify a format that includes all the precision, you can use the String.Format() method. The example that James gives would look like this:
String.Format("{0:yyyy-MM-dd HH:mm:ss.ffffff}", ObjectValue);
I don't know what that will do when you pass it something that's not a date.
Perhaps a simpler approach is to add a special case when you've already got a date object:
public DateTime? DateValue
{
get
{
DateTime value = ObjectValue as DateTime;
if (value != null) return value;
return DateTime.TryParse(ObjectValue.ToString(), out value) ? value : new DateTime?();
}
}
public DateTime? DateValue
{
get
{
DateTime value;
bool isDate = DateTime.TryParse(ObjectValue.ToString(), out value);
return isDate ? new DateTime?(value) : new DateTime?();
}
}
I don't know if this is the same in .NET, but in Java the equals often will only compare if the instances are the same, not if the values are the same. You'd instead want to use compareTo.