public DbSet JobLevels { get; set; } public DbSet Countries { get; set; } public DbSet Races { get; set; } public DbSet Languages { get; set; } public DbSet Titles { get; set; }
public ActionResult Edit(DropDownListModel model, Guid) { var dbSet = _dbContext.Countries; var newItems = model.Items.Where(i => i.IsNew && !i.IsDeleted).Select(i => new { i.Name }); foreach (var item in newItems) { if (!string.IsNullOrWhiteSpace(item.Name)) { var undead = ((IEnumerable)dbSet).FirstOrDefault(p => p.Name.ToLower() == item.Name.ToLower()); if (undead != null) { // Assign new value to update to the new char. case if present. undead.Name = item.Name; undead.IsDeleted = false; _dbContext.SaveChanges(); continue; } var newPair = new Country { Name = item.Name }; dbSet.Add(newPair); _dbContext.SaveChanges(); } } return RedirectToAction("Edit", new {listName = model.ListName}); }
我怎么能解决我的问题,现在我需要一个控制器为每个DbContext成员,如上面的DbSet Countries致力于DbSet Countries ?
namespace Your.Project.Interfaces { /// /// Represents an entity used with Entity Framework Code First. /// public interface IEntity { /// /// Gets or sets the identifier. /// /// /// The identifier. /// int Id { get; set; } } }
现在,每个具体实体都需要实现此接口:
public class MyEntity : IEntity { #region Implementation of IEntity /// /// Gets or sets the identifier. /// /// /// The identifier. /// public int Id { get; set; } #endregion // Other POCO properties... }
我发现这是最佳实践,不是为每个实体创建单独的接口,除非您在高测试环境中工作。 实际上,接口应该只在需要抽象级别的地方使用; 主要是当多个具体类inheritance时,或者使用过度热情的Inversion of Control引擎时。 如果您的生产模型中的所有内容都具有接口,那么您的架构很可能存在重大缺陷。 无论如何,足够漫无边际。
现在我们已经将所有实体“制定了策略”,我们可以使用MEF来整理它们并在您的上下文中填充集合。
在您的上下文中,添加一个新属性:
/// /// Gets a dynamically populated list of DbSets within the context. /// /// /// A dynamically populated list of DbSets within the context. /// [ImportMany(typeof(DbSet))] public IEnumerable> Sets { get; private set; }
这里的[ImportMany(typeof(DbSet))]允许MEF填充集合。
接下来,将相应的Export属性添加到上下文中的每个DbSet:
[Export(typeof(DbSet))] public DbSet MyEntities { get; set; }
// Instantiate the Sets list. Sets = new List>(); // Create a new Types catalogue, to hold the exported parts. var catalogue = new TypeCatalog(typeof (DbSet)); // Create a new Composition Container, to match all the importable and imported parts. var container = new CompositionContainer(catalogue); // Compose the exported and imported parts for this class. container.ComposeParts(this);
现在,运气好的话,你应该在你的上下文中有一个动态填充的DbSet列表。
我使用此方法允许通过扩展方法轻松截断所有表。
/// /// Provides extension methods for DbSet objects. /// public static class DbSetEx { /// /// Truncates the specified set. /// /// The type of the entity. /// The set. /// The truncated set. public static DbSet Truncate(this DbSet set) where TEntity : class, IEntity { set.ToList().ForEach(p => set.Remove(p)); return set; } }
我在上下文中添加了一个方法来截断整个数据库。
/// /// Truncates the database. /// public void TruncateDatabase() { Sets.ToList().ForEach(s => s.Truncate()); SaveChanges(); }
#region Dynamic Table List /// /// Gets a dynamically populated list of DbSets within the context. /// /// /// A dynamically populated list of DbSets within the context. /// public List> Tables { get; private set; } /// /// Gets a dynamically populated list of DbSets within the context. /// /// /// A dynamically populated list of DbSets within the context. /// [ImportMany("Sets", typeof (DbSet
接下来,从构造函数运行CompileSetsList() Facade(显示Web的最佳实践):
public MvcApplicationContext() { // Enable verification of transactions for ExecuteSQL functions. Configuration.EnsureTransactionsForFunctionsAndCommands = true; // Disable lazy loading. Configuration.LazyLoadingEnabled = false; // Enable tracing of SQL queries. Database.Log = msg => Trace.WriteLine(msg); // Use MEF to compile a list of all sets within the context. ComposeSetsList(); }
然后,只需装饰你的DbSet <> s:
/// /// Gets or sets the job levels. /// /// /// The job levels. /// [Export("Sets", typeof(DbSet))] public DbSet JobLevels { get; set; }