I need help formatting my link query properly, I am using EF 3.5:
Dim mediators = (From m In entity.Mediators _
Where m.MediatorAvailabilities.Available = "Weekends"
Where (m.isActive = True) _
Order By m.Sequence _
Select New RankingCriteria() With { _
.FirstName = m.FirstName, _
.LastName = m.LastName, _
.CompanyName = m.CompanyName, _
.PhoneHome = m.PhoneHome, _
.PhoneWork = m.PhoneWork, _
.PhoneMobile = m.PhoneMobile, _
.Email = m.Email _
}).ToList()
I have a navigation property in Mediators to MediatorAvailabilities I want to do something like what is in where clause above in order to filter my results. It's not letting me navigate to the appropriate column by doing this: m.MediatorAvailabilities.Available.
How do I do this filter properly?
Thanks, Justin.
You will need to use the Any method. I dont know the proper VB syntax, but it should look something like this:
Where m.MediatorAvailabilities.Any(ma => ma.Available = "Weekends")
Related
I am reading this tutorial https://www.stackbuilders.com/blog/nonsense-getting-started-with-reason-and-reason-react/. One of the problems I am facing is that api.noopschallenge.com is now dead. I replaced the API call to this https://random-word-api.herokuapp.com/word?number=20 This works but returns a Json Array. I have to convert the Json Array to list(string).
I modified the decodeWords function as
let decodeWord = (json: Js.Json.t) : list(string) =>
switch(Js.Json.decodeArray(json)) {
| None => []
| Some(array) => Belt.Array.map(Js.Json.decodeString, array)
};
But this gives me error
This has type:
Js.Json.t => option(Js.String.t) But somewhere wanted:
array('a)
How do I convert the Json Array to list(string)?
Two problems:
You've switched the arguments to Belt.Array.map around.´array` should come first.
Since decodeString returns an option(string) instead of just a string, you'll have to deal with the Nones somehow. Using Belt.Array.keepMap is a shorter way of just ignoring them.
let decodeWords = (json: Js.Json.t): list(string) =>
switch (Js.Json.decodeArray(json)) {
| None => []
| Some(array) =>
array->Belt.Array.keepMap(Js.Json.decodeString)->Belt.List.fromArray
};
But using the Js.Json API directly is rather cumbersome. You might want to consider using a third-party json decoding library such as bs-json (disclaimer: authored by me) instead. Then it would be as simple as:
let decodeWords = Json.Decode.(list(string))
Or, if you still want it to return an empty list instead of raising an exception on decode failure:
let decodeWords = Json.Decode.(withDefault([], list(string)))
I think I resolved it myself. but if you know of a better solution then please let me know
let decodeWords = (json: Js.Json.t) : list(string) =>
switch(Js.Json.decodeArray(json)) {
| None => []
| Some(array) => Belt.Array.reduce(array, [], (acc, value) => {
switch(Js.Json.decodeString(value)) {
| None => acc
| Some(v) => [v, ...acc]
}
})
};
I am trying to make the following call:
UPDATE MyTable SET path = ? WHERE instr(title, ?) AND start - ? < 60
However I have not been able to use instr with GRDB.
_ = try dbQueue?.write { db in
try MyTable
.filter(Column("start") > date - 60)
.filter(title.contains(Column("title")))
.updateAll(db,
Column("path").set(to: path)
)
}
How can I do this correctly? Could I also run a raw query instead? How can I fill the ? with my variables if using a raw query?
GRDB does not ship with built-in support for the instr function. You can define it in your code:
func instr(_ lhs: some SQLExpressible, rhs: some SQLExpressible) -> SQLExpression {
SQL("INSTR(\(lhs), \(rhs))").sqlExpression
}
// SELECT * FROM myTable WHERE instr(?, title)
let title: String = ...
let request = MyTable.filter(instr(title, Column("title")))
// UPDATE myTable SET path = ? WHERE instr(?, title)
let path: String = ...
try request.updateAll(db, Column("path").set(to: path))
See the How do I print a request as SQL? faq in order to control the SQL generated by GRDB.
Here is how I solved it with raw SQL in case it is too complicated to extend the framework.
I choose so, because I think this is easier to understand for someone who needs to read the code and has no experience with GRDB or frameworks in general.
do {
var dbQueue:DatabaseQueue? = try DatabaseQueue(path: "PATH_TO_DATABASE")
try dbQueue?.write { db in
try db.execute(
sql: "UPDATE MyTable SET path = :path WHERE instr(title, :title)",
arguments: ["path": path, "title": title]
)
}
} catch {
print("UPDATE MyTable \(error)")
}
I'm new to rust and was working on a generic database viewer app using SQLX. Now I've stumbled upon a problem. While querying like a simple
SELECT * FROM TABLE_NAME
Now the problem is that I don't know the type of rows and columns before hand. So how should I parse the queries?
I've tried the following from this post
for r in row {
let mut row_result: Vec<String> = Vec::new();
for col in r.columns() {
let value = r.try_get_raw(col.ordinal()).unwrap();
let value = match value.is_null() {
true => "NULL".to_string(),
false => {
let mat = value.as_str();
match mat {
Ok(m) => m.to_string(),
Err(err) => {
dbg!(err);
"ERROR".to_string()
}
}
}
};
// println!("VALUE-- {:?}", value);
row_result.push(value);
}
result.push(row_result);
}
The problem is that for some columns it's returning like this. Like for the ID columns
"\u0000\u0000\u0000\u0000\u0000\u0000\u0000\u0004"
and for some i'm getting the following error in the dbg! macro
Utf8Error {
valid_up_to: 2,
error_len: Some(
1,
),
}
Anyone can help me here?
BTW I'm using Postgres so all row types are of PgRow
2: Follow up. I was able to get the types of the columns from the information_schema but the problem seems to be that those will be in String and I couldn't find any way to convert those into rust types, like INT8 -> i64, TEXT -> String. Something like that.
I am trying to create a type safe data access layer in F# using FSharp.Data.SqlClient type providers to be callable from C#. I have highly complicated SQL queries that are performance critical but there are also several variations.
Given the following (obviously simplified schema):
CREATE TABLE [dbo].[company] (
[id] INT IDENTITY (1, 1) NOT NULL,
[name] VARCHAR (50) NOT NULL)
I have the following F# code:
module CompanyDAL =
open FSharp.Data // requires FSharp.Data.SqlClient package
[<Literal>]
let conn = "Data Source=(localdb)\ProjectsV13;Initial Catalog=TESTDB;Integrated Security=True;Pooling=False;Connect Timeout=30"
[<Literal>]
let baseQuery = "select id, name from company where 1 = 1 "
[<Literal>]
let filterById = "and id = #id"
[<Literal>]
let filterByName = "and name = #name"
[<Literal>]
let queryFilteredById = baseQuery + filterById
type GetCompanyById = SqlCommandProvider<queryFilteredById, conn>
[<Literal>]
let queryFilterbyName = baseQuery + filterByName
type GetCompanyByName = SqlCommandProvider<queryFilterbyName, conn>
type GetAllCompanies = SqlCommandProvider<baseQuery, conn>
type Company = {
Name : string
id : int
}
let getCompanyById (runtimeConn:string) =
async {
use query = new GetCompanyById(runtimeConn)
let! result = query.AsyncExecute(id = 10)
return result
|> Seq.map (fun x ->
{ Name = x.name
id = x.id })
|> Seq.toArray
} |> Async.StartAsTask
let getCompanyByName (runtimeConn:string) =
async {
use query = new GetCompanyByName(runtimeConn)
let! result = query.AsyncExecute(name = "abc" )
return result
|> Seq.map (fun x ->
{ Name = x.name
id = x.id })
|> Seq.toArray
} |> Async.StartAsTask
let getAllCompanies (runtimeConn:string) =
async {
use query = new GetAllCompanies(runtimeConn)
let! result = query.AsyncExecute()
return result
|> Seq.map (fun x ->
{ Name = x.name
id = x.id })
|> Seq.toArray
} |> Async.StartAsTask
Is there any way I can reduce the number of duplication while maintaining the raw performance of type safe raw queries?
I've tried using
type GetCompany = SqlEnumProvider<baseQuery, conn, provider>
Then I can write this code
GetCompany.Items |> Seq.where(fun (id, name) -> name = "xxx") |> printfn "%A"
So I can avoid duplication and pass a generic predicate fun (id, name) -> to the only GetCompany type.
Similarly,
GetCompany.Items |> Seq.where(fun (id, name) -> id = "1")
would work as well.
Note
Anyway, notice that the above will filter in memory. In fact Dynamic SQL is not permitted with this library, because it relies only on static analysis at compile time. If you need to construct queries dynamically, you can revert to raw ADO.NET or other light ORM.
I am using Entity Framework 3.5. My model has a Mediator table and a MediatorAvailabilities table. Most Mediators do not have an entry in MediatorAvailabilities (Availability = Null) but I still need to bring back the mediator whether or not there is a related MediatorAvailabilities.
My query below is only bring back a mediator if there is a related Availability. Again how do I get mediators even if Availability = null?:
Dim mediators = (From m In entity.Mediators.Include("MediatorAvailabilities") _
Where(m.MediatorAvailabilities.Any(Function(a) a.Availability = String.Empty Or a.Availability.Contains("Weekends") = True))
Where (m.isActive = True) _
Order By m.Sequence _
Select New RankingCriteria() With { _
.FirstName = m.FirstName, _
.LastName = m.LastName, _
.CompanyName = m.CompanyName, _
.PhoneHome = m.PhoneHome, _
.PhoneWork = m.PhoneWork, _
.PhoneMobile = m.PhoneMobile, _
.Email = m.Email _
}).ToList()
What's the correct way to do this?
I think you need to add a.Availability is Nothing in your Any method call like so:
Where(m.MediatorAvailabilities.Any(Function(a) a.Availability is Nothing Or a.Availability = String.Empty Or a.Availability.Contains("Weekends") = True))