简体   繁体   中英

Where to write custom data access method for EF6 code first

I am using Entity Framework 6 code first for my data access layer.

I understand that as of version 6, the DbContext implements the Unit of Work pattern, and each DbSet implements the repository pattern.

With that being the case, where should custom access method be placed in this architecture. Ie. methods that run queries against the entity.

For reference, my data context class looks like:

public class DatabaseContext : DbContext
{
    public DatabaseContext() : base("DatabaseContext ")
    {
    }

    public virtual DbSet<Account> Account { get; set; }
    public virtual DbSet<Country> Country { get; set; }
    etc...
}

And my entities are generally in the form:

public class Account
{
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int AccountId { get; set; }

    [Required]
    [MaxLength(255)]
    public string Name { get; set; }

    etc...
}

My guess is these methods would go in the entity class itself, which would allow me to access them in the form DataContext.Account.GetAccountById (for example):

public class Account
{
    [DatabaseGenerated(DatabaseGeneratedOption.Identity)]
    public int AccountId { get; set; }

    [Required]
    [MaxLength(255)]
    public string Name { get; set; }

    public Account GetAccountById(int accountId)
    {
        // but how do I get the data context?
    }
}

The problem with this, of course, is that I can't access the DataContext from inside the Entity.

Can anyone advise?

EDIT

I have come up with this method, which allows me access to the DbContext and to mock the call. Can anyone confirm if this is reasonable?

public class AccountDbSet<T> : DbSet<T> where T : class
{
    public virtual T GetAccountById(int id)
    {
        return this.Find(id);
    }
}

Then the Data Context:

public class DatabaseContext : DbContext
{
    public DatabaseContext () : base("DatabaseContext ")
    {
    }

    public virtual AccountDbSet<Account> Account { get; set; }
    etc...
}

I do not know if there is a built-in EntityFramework functionality for doing this, but talking about C# in general, you may create an extension class:

public static class EntityFrameworkExtensions 
{
    public static Account GetAccountById(this DbSet<Account> dbSet, int accountId) 
    {
        return dbSet.Find(accountId);
        // or dbSet.FirstOrDefault(x => x.Id == accountId) for non-primary key columns
    }
}

Then, somewhere in your code:

int id = DataContext.Account.GetAccountById(5);

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