Multiply VFP databases and passing connection strings to EF6 DbContext

Apr 3, 2014 at 10:22 AM
We have multiply VFP databases with the same schemas in different data paths. We want to pass a selected \datapath\company.dbc connection strings to our DataLayer.CustomerContext which is passed to BaseContext<TContext>, in doing so we get the error below:

'ERROR DataLayer.CustomerContext' must be a non-abstract type with a public parameterless constructor in order to use it as parameter 'TContext' in the generic type or method 'DataLayer.UnitOfWork<TContext>' C:_Lesgets\CustomerRepository\Customer_Accessor.cs CustomerRepository

Could you please give me some assistants, I want to pass a different VFPConnection based on the selected database to BaseContext but my constructor in CustomerContext to the abstract BaseContext is incorrect. The call to BaseContext needs some attention as well.

Our model is reversed engineered, CodeFirst, EF6, using VfpEntityFrameworkProvider.
We are using Julie Lerman’s Repository/UnitOfWork pattern.
We don’t want to use connection strings from *.config files we want code based configuration.
Calls

1/T1ViewModel
2/Customer_Accessor this sets up the uow and the repository
3/CustomerContext this passes the context to BaseContext
4/BaseContect this inilizes the database and send the connection string to : DbContext

code listed in order as above

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using Xceed.Wpf.DataGrid;
using Xceed.Wpf.DataGrid.Converters;
using Xceed.Wpf.DataGrid.Print;
using Xceed.Wpf.DataGrid.Stats;
using Xceed.Wpf.DataGrid.ValidationRules;
using Xceed.Wpf.DataGrid.Views;
using Xceed.Wpf.DataGrid.Views.Surfaces;
using Xceed.Wpf.Controls;
using Xceed.Wpf.DataGrid.ThemePack;
using Xceed.Wpf.DataGrid.Settings;
using Xceed.Wpf.DataGrid.Export;
using Caliburn.Micro;
using System.ComponentModel.Composition;
using System.Collections.ObjectModel;

using System.Data.Entity.Validation;
using System.Dynamic;
using System.Windows.Controls.Primitives;


using System.ComponentModel.Composition.Hosting;

using CustomerRepository;
using DataLayer;
using DataModelCompany.Models;
using VfpEntityFrameworkProvider;


namespace Encore.WpfEF.ViewModels
{
[Export(typeof(T1ViewModel))]
public class T1ViewModel : DataViewModelBase
{
    readonly IWindowManager windowManager;
    private readonly IEventAggregator eventAggregator;
    private  Customer_Accessor _customerAccessor;


    [ImportingConstructor]
    public T1ViewModel(IWindowManager passedWindowManager, PassValueList passedParameters, IEventAggregator eventAggregator, string encoreAppInfo)
        : base(passedWindowManager, passedParameters, eventAggregator, encoreAppInfo)
    {
        windowManager = passedWindowManager;
        eventAggregator = eventAggregator;
        _customerAccessor = new Customer_Accessor();


    }


    public void Save()
    {


    }


     public void AddressViaUOW()
    {
        //var connectionString = @"C:\encore.v9\userdata\DATAPLUS\Company.DBC";
        //var connection = new VfpConnection(connectionString);
        //using (var context = new CodeFirstContext(connection))
        //{
        //    var address = context.Addresses.ToArray();
        //}
        //var ag = _customerAccessor.Repo.All.ToList();
    }

     public void AddressViaFind()
     {
         var ag = _customerAccessor.Repo.Find(1);

     }

    public void AddressDelete()
     {

         _customerAccessor.Repo.Delete(146);
         _customerAccessor.Save();

       }

}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using DataLayer;
using DataLayer.Interfaces;
using DataModelCompany.Models;




namespace CustomerRepository
{
public class Customer_Accessor
{
private readonly UnitOfWork<CustomerContext> _uow;
private readonly CustomerRepository _repo;
public Customer_Accessor()
{
 _uow = new UnitOfWork<CustomerContext>();
 _repo=new CustomerRepository(_uow);
}




public CustomerRepository Repo
{
  get { return _repo; }
}

public void Save()
{
  _uow.Save();
}

}

public class CustomerRepository : ICustomerRepository
{
private readonly ICustomerContext _context;
public CustomerRepository(IUnitOfWork uow)
{
    _context = uow.Context as ICustomerContext;
}

public IQueryable<Address> All
{
    get {   return _context.Addresses; }
}

//public IQueryable<Promotion> AllIncluding(params Expression<Func<Promotion, object>>[] includeProperties)
//{
//  IQueryable<Promotion> query = _context.Promotions;
//  foreach (var includeProperty in includeProperties)
//  {
//    query = query.Include(includeProperty);
//  }
//  return query;
//}

public Address Find(int id)
{
    return _context.Addresses.Find(id);
}

//public void InsertOrUpdate(Promotion promotion)
//{
//  if (promotion.PromotionId == default(int)) // New entity
//  {
//    _context.SetAdd(promotion);
//  }
//  else        // Existing entity
//  {
//    _context.SetModified(promotion);

//  }
//}

public void Delete(int id)
{
    var address = _context.Addresses.Find(id);
    _context.Addresses.Remove(address);
}

//public List<Order> OrdersViaPromotion(Promotion promo)
//{
//  if (promo.StartDate <= DateTime.Today)
//  {
//    return _context.Orders.Where(o => o.PromotionId == promo.PromotionId).ToList();
//  }
//  return null;
//}

//public Nullable<int> CountOfOrdersGenerated(int promotionId, DateTime promotionStartDate)
//{
//  if (promotionStartDate <= DateTime.Today)
//  {
//    return _context.Orders.Count(o => o.PromotionId == promotionId);
//  }
//  return null;
//}

public void Dispose()
{

}
}

}

using System;
using System.Data;
using System.Data.Entity;
using System.Data.Entity.Infrastructure;
using DataModelCompany.Models;
using DataModelCompany.Models.Mapping;
using VfpEntityFrameworkProvider;


namespace DataLayer
{
public interface ICustomerContext : IContext
{
    IDbSet<Account> Accounts { get; }
    IDbSet<Address> Addresses { get; }
    IDbSet<Addrlink> Addrlinks { get; }
    IDbSet<Contacth> Contacths { get; }
    IDbSet<Contact> Contacts { get; }
    IDbSet<Supplier> Suppliers { get; }
    IDbSet<Cusgrp> Cusgrps { get; }
    IDbSet<Webste> Webstes { get; }
    IDbSet<Term> Terms { get; }
}


[DbConfigurationType(typeof(VfpDbConfiguration))]
public class CustomerContext : BaseContext<CustomerContext>, ICustomerContext
{
    private VfpConnection connection;

    public IDbSet<Account> Accounts { get; set; }
    public IDbSet<Address> Addresses { get; set; }
    public IDbSet<Addrlink> Addrlinks { get; set; }
    public IDbSet<Contacth> Contacths { get; set; }
    public IDbSet<Contact> Contacts { get; set; }
    public IDbSet<Supplier> Suppliers { get; set; }
    public IDbSet<Cusgrp> Cusgrps { get; set; }
    public IDbSet<Webste> Webstes { get; set; }
    public IDbSet<Term> Terms { get; set; }
    public void SetModified(object entity)
    {
        Entry(entity).State = EntityState.Modified;
    }

    public void SetAdd(object entity)
    {
        Entry(entity).State = EntityState.Added;
    }

    static CustomerContext()
    {
        Database.SetInitializer<CustomerContext>(null);
    }

    public CustomerContext(VfpConnection connection)
        : base(connection)
    {
        var connectionString = @"C:\encore.v9\userdata\DATAPLUS\Company.DBC";
         connection = new VfpConnection(connectionString);
    }




    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
        modelBuilder.Configurations.Add(new AccountMap());
        modelBuilder.Configurations.Add(new AddressMap());
        modelBuilder.Configurations.Add(new AddrlinkMap());
        modelBuilder.Configurations.Add(new ContactMap());
        modelBuilder.Configurations.Add(new ContacthMap());
        modelBuilder.Configurations.Add(new SupplierMap());
        modelBuilder.Configurations.Add(new CusgrpMap());
        modelBuilder.Configurations.Add(new WebsteMap());
        modelBuilder.Configurations.Add(new TermMap());
    }

}

}

using System.Data.Entity;
using VfpEntityFrameworkProvider;
namespace DataLayer
{
public abstract class BaseContext<TContext> : DbContext
  where TContext : DbContext
{
static BaseContext()
{
  Database.SetInitializer<TContext>(null);
}

public BaseContext(VfpConnection connection)
        : base(connection, true) {
    }
}
}
Marked as answer by andygl on 4/4/2014 at 2:10 AM
Coordinator
Apr 3, 2014 at 11:56 PM
You didn't include the code for the UnitOfWork class but it seems like that class is trying to create CustomerContext using a constructor that doesn't include any parameters - which won't work because that class doesn't include a parameterless constructor. The UnitOfWork code most likely includes a line something like "context = new TContext()." Based on the code you provided... you need to figure out how to pass in a VfpConnection to the CustomerContext constructor.
Apr 4, 2014 at 6:13 PM
We now find the connectionName in C:\Program Files (x86)\Microsoft Visual FoxPro 9\vfp9.exe.config and then change the connection string like so Database.Connection.ConnectionString = ConnectionString; in BaseContext().
We required this file C:\Program Files (x86)\Microsoft Visual FoxPro 9\vfp9.exe.config while calling .net forms from within VFP via com otherwise, .net errored with "cannot find connection string".

using System.Data.Entity;

namespace DataLayer
{
public class BaseContext<TContext>
: DbContext where TContext : DbContext
{
static BaseContext()
{
  Database.SetInitializer<TContext>(null);
}


public BaseContext(string nameOrConnectionString, string ConnectionString)
    : base(nameOrConnectionString)
{

    Database.Connection.ConnectionString = ConnectionString;

}



}
}
Marked as answer by andygl on 4/4/2014 at 10:14 AM