• 0

Generic Constraint for a Record Type and MySQL EF Question


Question

First question,

Not sure if I can constrain this better,

let MapRecord<'t when 't : comparison and 't : equality and 't : not struct> =
/*OMITTED*/
this calls PreComputeRecordConstructor to create a record based on data ...

Second question,

AFAIK F# has no type provider that supports MySQL - only MS SQL.

Thus, if I want to do parsing on MySQL data the best solution is to,

1. Create a C# library with the generated EDMX file (database first)

2. Reference said library in F# code in use it

How sane does this sound? Is there a better solution?

Also, on the same topic as question 2,

let inline getId item = (^a : (member ID : int) item)
don't work in EF queries. EF actually sees the getId funct and does not recognize it throwing an error.

I thought that such code gets resolved and inlined into a direct .memberName call when compiled in IL?

Link to comment
Share on other sites

4 answers to this question

Recommended Posts

  • 0

The SQLProvider supports MySQL, according to the project home page.

 

The way inline resolves static generic constraints is by - as the name implies - inlining: it won't work if you assign the function to a non-inline one.

Link to comment
Share on other sites

  • 0

The SQLProvider supports MySQL, according to the project home page.

 

The way inline resolves static generic constraints is by - as the name implies - inlining: it won't work if you assign the function to a non-inline one.

Hmm. I am hesitant on trying that out as it is a 3rd party solution.

EDIT: I mean, would you use it or rely on a mutli-project multi-language setup instead?

I worked around by adding an interface to the generated classes and using 'a when 'a :> IFooBar - granted more code.

But I still don't get it, such code works just fine after the query is returned but

when using to filter output from a DbSet it fails at runtime with an EF error complaining that it doesn't support it.

Is it just not possible to use inlined generic functions with EF's _ DbSet query?

This works because queryDb returns the list result of an executed query and then inlined func is applied,

    let inline private getCode item = (^a : (member Code : _) item)
    let inline private getType item = (^a : (member Type : _) item)
    let inline private getDescription item = (^a : (member Description : _) item)

    let inline private getCodeInfo item = getCode item, getDescription item
    let inline private getTypeInfo item = getType item, getDescription item

    let inline private xInfo (table : FooBarEntities -> _ DbSet) f = 
        queryDb (fun db -> table db) |> List.map f |> Map.ofList

    let inline private codeInfo table = xInfo table getCodeInfo
    let inline private typeInfo table = xInfo table getTypeInfo
EDIT:

Actually I can't see to do something like,

        query {
            for item in set do
            where (filter item) //(filter item)
            select item
        }
at all. Seems this is completely different than C# .Where(filter) function.

I am not sure how to approach this. I will try to use C#' Where with an Expression in F# instead.

EDIT: ###### that I will write these extensions methods in C# - can't figure out the heads and taiils of why EF complains about Invoke

Edited by _Alexander
Link to comment
Share on other sites

  • 0
Hmm. I am hesitant on trying that out as it is a 3rd party solution.

EDIT: I mean, would you use it or rely on a mutli-project multi-language setup instead?

My guess is that working with a type provider should be less painful than EF. But there are several options, perhaps the documentation here can answer some of your woes with LINQ etc.:

http://fsharp.org/guides/data-access/#sql-data-access

 

To be honest, I know very little about EF, SQL and type providers, so unless there are F# afficionados other than me here, I would suggest you ask the question on Stackoverflow. F#'s community is very supportive, but not well represented here.

Link to comment
Share on other sites

  • 0

If anyone is wondering on a record constraint, I got this by looking at the metadata from a C# project,

public sealed class TestRecord : IEquatable<TestRecord>, IStructuralEquatable, IComparable<TestRecord>, IComparable, IStructuralComparable
so F# constraint would look like,

    let RecordMap<'record 
        when 'record :> IEquatable<'record> 
        and 'record :> IStructuralEquatable 
        and 'record :> IComparable<'record>
        and 'record :> IComparable
        and 'record :> IStructuralComparable
        and 'record : comparison 
        and 'record : equality 
        and 'record : not struct> =
I think I figured out the EF.

EF uses reflection and Expressions to determine what query to build - the way I was doing it was NOT an F# specific issue - same issue happens in C#.

I hope Microsoft will expand F# to support ASP.NET, WPF, and refactoring in the future. Good language - horrid support.

Link to comment
Share on other sites

This topic is now closed to further replies.