little assistance here with my query using dapper, been getting error Message = "ORA-00936: missing expression\n" on my query. I would like to know what am I missing here?
public class LocationDto
{
public int LocationId { get; set; }
public int RouteId { get; set; }
public string StartTime { get; set; }
public string Location { get; set; }
}
// Query Below
using (OracleConnection connection = new OracleConnection(ConfigurationManager.ConnectionStrings["ConnectionString"].ConnectionString))
{
try {
var x = connection.QueryAsync<LocationDto>("Select ROUTE_ID as RouteId, SCHEDULE_STOP as Location, START_TIME as StartTime From SCHEDULE WHERE ROUTE_ID = #Id", new { input.RouteId }).Result.ToList();
}
catch (Exception ex)
{
}
}
Firstly with Oracle queries you need to use : instead of # to denote a parameter placeholder.
Then secondly this code:
new { input.RouteId }
will produce an object with a property called RouteId.
This RouteId does not match the name of the parameter in your query, which is Id. They need to match, otherwise there's no way for the database to bind the parameter to the correct input value.
You can either
change the Sql query:
WHERE ROUTE_ID = :RouteId
OR
change the C#:
new { Id = input.RouteId }
and use :Id in the SQL.
It doesn't really matter which, the important thing is that the names match.
Related
I'm trying to pull data from an Access database using dapper. I have the following class defined to use the fields from the access database that I need to read. I then tried to pull the data using the code below. When I run this only blanks come back. The number of blanks match the number of records in the data table.
I tried to use a shorter sql string with the same results.
I can't find any information on this issue, does anyone have any ideas about this?
public class DLabResults
{
public int ResultsFolderNumber { get; set; }
public int Request { get; set; }
public int Release { get; set; }
public string Formulation { get; set; }
public string Container { get; set; }
public string Closure { get; set; }
public string Shipper { get; set; }
// public string Label_Back { get; set; }
// public string Label_Front { get; set; }
public string FilePath { get; set; }
}
public void LoadDapperDLabResults(List<DLabResults> items)
{
string sql = "";
//sql = "SELECT tblResults_Results.R_Project_Assignment, tblResults_Results.R_Project_Request, tblResults_Results.R_Project_Release, tblResults_Results.R_Formulation, tblResults_Results.R_Closure, tblResults_Results.R_Container, tblResults_Results.R_Shipper, '' AS Blank1, '' AS Blank2, tblResults_Results.R_Test_FullPath FROM tblResults_Results WHERE(((tblResults_Results.R_Formulation)Like '*' & [Formulation] & '*') AND ((tblResults_Results.R_Closure)Like '*' & [Closure] & '*') AND((tblResults_Results.R_Container)Like '*' & [Container] & '*') AND((tblResults_Results.R_Shipper)Like '*' & [Shipper] & '*')) ORDER BY tblResults_Results.R_Project_Assignment, tblResults_Results.R_Project_Request, tblResults_Results.R_Project_Release;";
sql = "SELECT * FROM tblResults_Results";
using (OleDbConnection connection = new OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\\Users\\DavidsoJ\\Desktop\\Fixed Push Workbooks\\Redesigned Databases\\Development Lab Results Database.accdb"))
{
//var TM2 = connection.Query<DLabResults>(sql).ToList();
List<DLabResults> TM2 = connection.Query<DLabResults>(sql).ToList();
//add items to employess
if (items == null || items.Count < 1)
{
}
else
{
TM2.AddRange(items);
}
dataGridView1.DataSource = TM2;
}
}
The column names from the SQL query do not seem to match up with the properties of the desired object model DLabResults.
Either update the columns names returned from the query to match the object
SELECT tblResults_Results.R_Project_Request AS Request
/*, ... code removed for brevity */
FROM tblResults_Results
OR update the DLabResults property names to match the column names returned from the query
public class DLabResults {
public int R_Project_Request{ get; set; }
//... code removed for brevity
}
Either way, when using dapper the column names need to be mapped to object members in order for dapper to populate them.
I've been tasked to add a page to an API that we didn't build but are tasked to work on. The API is using C# MVC5. I don't really know MVC5, and but I'm attempting to keep the same design pattern that the rest of the API is using. I have to add functionality that will allow a user on the front end to upload a file to a server that will be processed for inserting into a SQL Server DB. This functionality will also return a list of all the files names and status of the imported files from a table in the DB.
The issue I'm having is converting a Datetime to a string in the LINQ query that is pulling the list of files.
I've attempted to try using this answer LINQ convert DateTime to string, but with no luck.
This is what I have so far, I've marked the line that is causing the issue:
[Route("ImportLogs", Name ="GetImportLogs")]
[HttpGet]
[ResponseType(typeof(List<IHttpActionResult>))]
public IHttpActionResult GetImportLogs()
{
var query =
from dbitem in db.ImportLogs
orderby dbitem.import_log_id
select new ImportLogDto()
{
Id = dbitem.import_log_id,
FileName = dbitem.import_file_name,
ImportTimeStamp = dbitem.import_timeStamp,
ImportStatus = dbitem.import_status,
ImportMessage = dbitem.import_message
};
query.ToList()
.Select(o => new ImportLogDto
{
Id = o.Id,
FileName = o.FileName,
ImportMessage = o.ImportMessage,
ImportStatus = o.ImportStatus,
ImportTimeStamp = o.ImportTimeStamp.ToString() //PROBLEM LINE
});
return Ok(query);
}
The error that I'm getting is
Cannot implicitly convert type 'string' to 'System.DateTime'
What am doing wrong? Any help would be appreciated. TIA.
EDIT:
Here is the DTO:
public class ImportLogDto
{
public int Id { get; set; }
public string FileName { get; set; }
public DateTime ImportTimeStamp { get; set; }
public string ImportStatus { get; set; }
public string ImportMessage { get; set; }
}
You are trying to assign a string into a DateTime so you get that exception. If you want to cast it to a string change your model as follows:
public class ImportLogDto
{
public int Id { get; set; }
public string FileName { get; set; }
public string ImportTimeStamp { get; set; } // Changed type
public string ImportStatus { get; set; }
public string ImportMessage { get; set; }
}
And then your query:
var query = (from dbitem in db.ImportLogs
orderby dbitem.import_log_id
select new {
Idbitem.import_log_id,
dbitem.import_file_name,
dbitem.import_timeStamp, // Still DateTime
dbitem.import_status,
dbitem.import_message
}).AsEnumerable(); // Retrieved from Database
.Select(o => new ImportLogDto
{
Id = o.import_log_id,
FileName = o.import_file_name,
ImportMessage = o.import_message,
ImportStatus = o.import_status,
ImportTimeStamp = o.import_timeStamp.ToString() // Changes to string
});
If you wnat to change the format of the DateTime for the API then then use its overload of ToString and specify a format:
ImportTimeStamp = o.ImportTimeStamp.ToString("dd/MM/yyyy HH24:MI:ss")
For more on the overload read: Custom Date and Time Format Strings
Your types are already DateTime, and since these types are tied to the backing data* you probably shouldn't change them. But where you return the values on the API you can really return anything you want. So an anonymous type could be a quick solution:
.Select(o => new // <--- notice no type definition here
{
Id = o.Id,
FileName = o.FileName,
ImportMessage = o.ImportMessage,
ImportStatus = o.ImportStatus,
ImportTimeStamp = o.ImportTimeStamp.ToString()
})
The compiler will know based on the type returned by .ToString() that you want ImportTimeStamp to be a string. You can then add formatters to .ToString() to customize the output however you like.
*If your DTO isn't actually tied to the database then you can change the type there from DateTime to string, of course. It's not really clear from the context of the code shown whether these are data DTOs or application DTOs.
I have ListView like this
<asp:ListView ID="ListView1" ItemType="test.Project"
SelectMethod="ListView1_GetData" runat="server">
I am trying to set the select method to a stored procedure using EF. the select method like this
public IQueryable<Test.Project> ListView1_GetData()
{
using (DREntities2 db=new DREntities2())
{
return db.GetLatestProjects().AsQueryable();
}
}
I get this error:
Cannot implicitly convert type 'System.Linq.IQueryable' to 'System.Linq.IQueryable'. An explicit conversion exists (are you missing a cast?)
If I remove the .AsQueryable(), I get this error:
Cannot implicitly convert type 'System.Data.Objects.ObjectResult' to 'System.Linq.IQueryable
Here is the definition of the GetLastestProjects_Result as returned by DREntities2 .GetLatestProjects():
public partial class GetLatestProjects_Result
{
public int ProjectID { get; set; }
public string Title { get; set; }
public string ShortDescr { get; set; }
public string Full_Descr { get; set; }
public int ProCatID { get; set; }
public bool Marquee { get; set; }
}
Your stored procedure is returning ObjectResult<Test.GetLatestProjects_Result> and you are trying to convert it to IQueryable<Test.Project>. To do this you need to convert using the Linq Select method. Assuming Test.GetLatestProjects_Result and Test.Project have the same properties:
public IQueryable<Test.Project> ListView1_GetData()
{
using (DREntities2 db=new DREntities2())
{
return db.GetLatestProjects().Select(p => new Test.Project
{
ProjectId = p.ProjectId,
Title = p.Title,
ShortDescr = p.ShortDescr,
Full_Descr = p.Full_Descr,
ProCatID = p.ProCatID,
Marquee = p.Marquee
}).AsQueryable();
}
}
A little late to the game, but others may be able to do the following. Assuming that Test.Project is an EntityType, in the Model Browser change the return type of your stored procedure in the EF Model to Test.Project instead of the default GetLatestProjects_Result "complex type" that is created.
Then, in your query you can take the result to a typed list, then call AsQueryable on the result.
Here is an example that calls an SP named GetAllRequestsByWorkflowState which returns TravelRequestSummaryView entities:
private IQueryable<TravelRequestSummaryView> GetApprovalRequests(int approvalState)
{
IQueryable<TravelRequestSummaryView> trsv = null;
try
{
var res = db.GetAllRequestsByWorkflowState(approvalState)
.ToList<TravelRequestSummaryView>();
trsv = res.AsQueryable();
}
catch (Exception ex)
{
sqlTraceManager.WriteTraceIf(ex, User.Identity.Name);
}
return trsv;
}
I have a table called Activity (Mobile service), and i add a query in reading:
Azure Script:
function read(query, user, request)
{
var param = request.parameters.UserLocation;
if(param)
{
var sql = "Select TOP 10 [NewsItemUrl], count(1) as CounterNews FROM [MobileServiceExtra].[ACTIVITY] WHERE [UserLocation] = ? GROUP BY [NewsItemUrl] ORDER BY CounterNews Desc";
mssql.query(sql,param, {success: function(results) {request.respond(statusCodes.OK, results);}});
}
//request.execute();
}
Client side:
public class ACTIVITY
{
public int Id { get; set; }
[JsonProperty(PropertyName = "UserLocation")]
public string _UserLocation { get; set; }
[JsonProperty(PropertyName = "NewsItemUrl")]
public string _NewsItemUrl { get; set; }
[JsonProperty(PropertyName = "NewsItemTitle")]
public string _NewsItemTitle { get; set; }
[JsonProperty(PropertyName = "NewsItemPublisher")]
public string _NewsItemPublisher { get; set; }
}
If I do the query in sql, I get 2 columns CounterNews and NewsItemUrl and where the Last is the number of times to repeat the url. However, I dont know how to get the data in column "CounterNews", i mean, when i want to get the query, i get to do with the Activity table (class) and obviously returns me the data correctly, but only NewsItemUrl column and the other fields are empty.
Client side:
private MobileServiceCollection<ACTIVITY, ACTIVITY> TopReadCollectionActivity;
private IMobileServiceTable<ACTIVITY> ACTIVITYTable = App.MobileService.GetTable<ACTIVITY>();
private async void LoadTop10()
{
var dict = new Dictionary<string, string>
{
{ "UserLocation", "United States" },
};
try
{
TopReadCollectionActivity = await ACTIVITYTable.WithParameters(dict).ToCollectionAsync();
}
catch (Exception ex)
{
string err = ex.Message;
}
}
if i create a class (table too)"Top10", azure give a error, because the table doen't exist. and
not want to create a new table.
how to get the query only two fields CounterNews and NewsItemUrl?
Perhaps you should just query the table directly using the OData support. This way your not confined to the structure of your table. Take a look at this for reference.
http://msdn.microsoft.com/en-us/library/windowsazure/jj677199.aspx
I'm trying to perform a very standard multi mapping query using Dapper, and I'm getting the following error. I also get another error occasionally when this seems to work, but I'm unable to reproduce it at the moment. I'll append it to this post if/when the first problem is solved.
Here is the query code:
const string storedProc = "dbo.GetStopsForRouteID";
var stops = conn.Query<RouteStop, MapLocation, RouteStop>(
storedProc, (stop, loc) =>
{
stop.Location = loc;
return stop;
}, new { RouteID = routeId }, commandType: CommandType.StoredProcedure);
In Dapper.cs on line 498:
var deserializer2 = (Func<IDataReader, TSecond>)info.OtherDeserializers[0];
info.OtherDeserializers is null which causes a NullReferenceException.
This is the guts of the stored procedure:
SELECT
RouteStops.StopID,
RouteStops.Name,
RouteStops.Description,
RouteStops.IsInbound,
RouteStops.Location.Lat as Latitude,
RouteStops.Location.Long as Longitude
FROM dbo.Routes
INNER JOIN dbo.StopsOnRoute ON
Routes.RouteID = StopsOnRoute.RouteID
INNER JOIN dbo.RouteStops ON
StopsOnRoute.StopID = RouteStops.StopID
WHERE Routes.RouteID = #RouteID
ORDER BY StopsOnRoute.SequenceNumber
I've had an extensive look at the dapper code but I can't find anything that seems out of place other than that TFirst's deserialiser isn't null, but TSecond's is. Could there be a problem when it creates TSecond's deserializer that leaves it as null?
Here are the types:
public class MapLocation
{
public double Latitude { get; set; }
public double Longitude { get; set; }
}
public class RouteStop {
public int StopID { get; set; }
public string Name { get; set; }
public string Description { get; set; }
public bool IsInbound { get; set; }
public MapLocation Location { get; set; }
}
Probably the main problem here is that you haven't told it how to "split"; try adding the parameter:
splitOn: "Latitude"
without that, as far as dapper can see there is no second result portion (it splits on Id by default).