简体   繁体   中英

MVC 4 late-bound DataContext entity LINQ reference

Long time listener, first time caller.

I'm probably taking the wrong approach to this, so any help would be fantastic.

I'm using C#, MVC 4, Code First, Entity Framework 4.3, & Razor.

I am trying to split out EF data classes & some methods into a separate class project so that they can generically be references by multiple other projects. I've created this simplified example to highlight the issue as much as I can.

So in a class project I have:

public MyGeneric(string name)
{
    ID = Guid.NewGuid();
    Name = name;
}

public Guid ID { get; set; }
public string Name { get; set; }


public void AddThis(MyGeneric obj)
{
    using (var db = Activator.CreateInstance<myDbContext>())
    {
        var myOthers = from mo in db.MyOther
                       where mo.OtherID == obj.ID
                       select mo;

        myOthers.ForEach(mo => db.MyOther.Add(mo));
        db.SaveChanges();
    }
}

And then I can reference this in a main project such as:

public class SampleInherit : MyGeneric
{
    public SampleInherit(string newName, string secName)
        : base(newName)
    {
        SecName = secName;
    }

    public string SecName { get; set; }


    public void DoSomething(SampleInherit obj)
    {
        base.AddThis(obj);
        // do other stuff
    }
}

What I'm trying to do is genericise (is that a word?) a few classes with their methods into a separate side project. This side project will supply base classes that will (in order of desired):

  • use EF DbContext to create/access the database,
  • allow more properties to be added,
  • supply method/procedures that affect the underlying data,
  • be renamed more appropriately for the main project.

Now if I just inherit the base classes into classes in the main project, it all works except for the base class reference myDbContext & the entity object references within the LINQ statements.

Can you late-bind the DataContext or have I painted my self into a corner here?

Cheers for all the help you can give.

I think what you're trying to do is implement the IRepository pattern. Basically you want to do is create a class project that contains your Entities and your IRepository. From there you create the concrete implementation of the IRepository by creating your Repository class. You use your business logic layer to access the repositories through an IRepository. And do your data access there.

public interface IRepository<T>
{
    IQueryable<T> Fetch();

    bool Insert(T entity);

    bool Update(T entity);
}

Then create your repository

public class MyRepository<TContext> : IRepository<EntityType> where TContext: DbContext, new()
{
    private TContext context;

    public MyRepository(TContext context)
    {
        this.context = context;
    }

    public IQueryable<T> Fetch()
    {
       return context.EntityTypes;
    }

    // Insert and update logic
}

Finally create your business logic

public class BusinessLogic
{
    private IRepository<EntityType> repository;

    public BusinessLogic(IRepository<EntityType> repository)
    {
        this.repository = repository;
    }

    public void Add(EntityType obj)
    {
      bool isNew = // check if new
      if(isNew)
      {
        this.repository.Insert (obj)    
      }
      else
      {
        this.repository.Update(obj);
      }
    }
}

Then call your business logic

IRepository<EntityType> repository = new MyRepository<MyDbContext>(new MyDbContext());
BusinessLogic service = new BusinessLogic(repository);

service.Add(new EntityType());

I do not think you want late-binding of the data context, It's better to use generics for performance considerations (as with the above example). Also with this method you can instantiate a data context and pass it around to your business services, so that entity framework can keep track of your entities rather than instantiate a new data context for each call to AddThis. Plus with this pattern you can do all sorts of cool things, such as use an IOC container like ninject to create those business services for you, and use Mocks to create unit tests for your code without having to hit the database (by mocking your repositories).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM