I have a one-to-many relationship between Dealer who can have many Cars .
I am trying to convert my C # code used for EF to F # ... The problem is that in my F # code it can get a Dealer fine, but it is not suitable for this Dealer ... it just returns null, but does it work in C #?
My code is:
C # Version
public class Dealer { public int ID { get; set; } public string Name { get; set; } public virtual ICollection<Car> Cars { get; set; } public Dealer() { Cars = new List<Car>(); } } public class Car { public int ID { get; set; } public string CarName { get; set; } public Dealer Dealer { get; set; } public int DealerId { get; set; } public Car() { Dealer = new Dealer(); } } public class MyContext : DbContext { public DbSet<Dealer> Dealers { get; set; } public DbSet<Car> Cars { get; set; } public MyContext() { Database.Connection.ConnectionString = "server=some;database=dbname;user id=uid;password=pwd"; } protected override void OnModelCreating(DbModelBuilder modelBuilder) { modelBuilder.Entity<Dealer>() .HasMany(x => x.Cars) .WithRequired(x => x.Dealer) .HasForeignKey(x => x.DealerId); modelBuilder.Entity<Car>() .HasRequired(x => x.Dealer) .WithMany() .HasForeignKey(x => x.DealerId); modelBuilder.Entity<Dealer>().ToTable("Dealers"); modelBuilder.Entity<Car>().ToTable("Cars"); } }
... Program.cs that are requested from the dealer and his machine:
static void Main(string[] args) { var ctx = new MyContext(); foreach (var s in ctx.Dealers.FirstOrDefault(x => x.ID == 1).Cars) { Console.WriteLine(s.CarName); } Console.Read(); }
Version F #
type Dealer() = let mutable id = 0 let mutable name = "" let mutable cars = List<Car>() :> ICollection<Car> member x.ID with get() = id and set v = id <- v member x.Name with get() = name and set v = name <- v abstract member Cars : ICollection<Car> with get, set override x.Cars with get() = cars and set v = cars <- v and Car() = let mutable id = 0 let mutable carName = "" let mutable dealer = Dealer() let mutable dealerId = 0 member x.ID with get() = id and set v = id <- v member x.CarName with get() = carName and set v = carName <- v member x.Dealer with get() = dealer and set v = dealer <- v member x.DealerId with get() = dealerId and set v = dealerId <- v type MyContext() = inherit DbContext("server=some;database=dbname;user id=uid;password=pwd") [<DefaultValue>] val mutable dealers : DbSet<Dealer> member x.Dealers with get() = x.dealers and set v = x.dealers <- v [<DefaultValue>] val mutable cars : DbSet<Car> member x.Cars with get() = x.cars and set v = x.cars <- v override x.OnModelCreating(modelBuilder:DbModelBuilder) = modelBuilder.Entity<Dealer>() .HasMany(ToLinq(<@ fun ka -> ka.Cars @>)) .WithRequired(ToLinq(<@ fun sk -> sk.Dealer @>)) .HasForeignKey(ToLinq(<@ fun fg -> fg.DealerId @>)) |> ignore modelBuilder.Entity<Car>() .HasRequired(ToLinq(<@ fun ak -> ak.Dealer @>)) .WithMany() .HasForeignKey(ToLinq(<@ fun ka -> ka.DealerId @>)) |> ignore modelBuilder.Entity<Dealer>().ToTable("Dealers") modelBuilder.Entity<Car>().ToTable("Cars")
... ToLinq Function:
let ToLinq (exp : Expr<'a -> 'b>) = let linq = exp.ToLinqExpression() let call = linq :?> MethodCallExpression let lambda = call.Arguments.[0] :?> LambdaExpression Expression.Lambda<Func<'a, 'b>>(lambda.Body, lambda.Parameters)
... and Program.fs that will deliver the Dealer and his cars:
let ctx = new MyContext() let joe = ctx.Dealers.Find(1) joe.Cars |> Seq.iter(fun x -> printfn "%s" x.CarName) printfn "DONE"
Any help is appreciated!
ebb
source share