如何推广使用DbSet< TEntity>一的DbContext成员? [英] How to generalise access to DbSet<TEntity> members of a DbContext?

查看:134
本文介绍了如何推广使用DbSet< TEntity>一的DbContext成员?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个的DbContext 与以下几个类型成员的:

 公共DbSet< JobLevel> JobLevels {获得;组; }
公共DbSet<国家>国家{获得;组; }
公共DbSet<种族与GT;种族{获得;组; }
公共DbSet<语言>语言{获得;组; }
公共DbSet<标题>标题{获得;组; }
 

所有这些都是其中T:IdNamePairBase ,其中有编号名称仅成员。我拼命想寻找与访问任何这些成员中,概括如下MVC3控制器code到一个控制器,一个共同的接口:

 公众的ActionResult编辑(DropDownListModel模型,GUID)
{
    VAR dbSet = _dbContext.Countries;
    VAR newItems = model.Items.Where(I => i.IsNew和放大器;&安培;!i.IsDeleted)。选择(I =>新建{i.Name});
    的foreach(在newItems VAR项)
    {
        如果(!string.IsNullOrWhiteSpace(item.Name))
        {
            变种不死=((&IEnumerable的所述; IdNamePairBase&GT)dbSet).FirstOrDefault(p值=> p.Name.ToLower()== item.Name.ToLower());
            如果(不死!= NULL)
            {
                //指定新的值更新到新的字符。情况下,如果present。
                undead.Name = item.Name;
                undead.IsDeleted = FALSE;
                _dbContext.SaveChanges();
                继续;
            }
            VAR newPair =新国家{名称= item.Name};
            dbSet.Add(newPair);
            _dbContext.SaveChanges();
        }
    }
    返回RedirectToAction(编辑,新{LISTNAME = model.ListName});
}
 

我怎么能去解决我的问题,现在我需要一个控制器为每个的DbContext 的成员,像一个以上专用于 DbSet<国家>国家

部分解决:随着类似下面GertArnold的回答线,之前我就知道关于 _dbContext.Set< T> 所有他强调了,我实现我的上下文类此方法来获取集合特定类型的:

 公开的IEnumerable< D​​bSet< T>> GetDbSetsByType< T>()其中T:类
{
    // VAR标志= BindingFlags.Public | BindingFlags.DeclaredOnly | BindingFlags.Instance;
    VAR道具=的GetType()。GetProperties中()
        。凡(P => p.PropertyType.IsGenericType和放大器;&安培; p.PropertyType.Name.StartsWith(DbSet))
        。凡(P => p.PropertyType.GetGenericArguments()所有(T =>:T == typeof运算(T)));
    返回props.Select(P =>(DbSet< T>)p.GetValue(本,NULL));
}
 

解决方案

有些泛化可以通过使用

  VAR dbSet = _dbContext.Set< T>
 

和把大部分的方法中的方法与泛型类型参数。

但是,应该有一个开关某处决定哪些类型应该指定和要创建的类型,因为我认为类型被作为模型的属性(是什么?)。因此,它可能不会真正看起来优雅,但很可能是短了很多,用干儿code。

I have a DbContext with several of the following type of members:

public DbSet<JobLevel> JobLevels { get; set; }
public DbSet<Country> Countries { get; set; }
public DbSet<Race> Races { get; set; }
public DbSet<Language> Languages { get; set; }
public DbSet<Title> Titles { get; set; }

All these are where T: IdNamePairBase, which has Id and Name members only. I am trying desperately to find a common interface with which to access any of these members, to generalise the following MVC3 controller code into one controller:

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<IdNamePairBase>)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});
}

How could I go about resolving my problem that right now I need one controller for each of the DbContext members, like the one above is dedicated to DbSet<Country> Countries?

PARTIAL SOLUTION: Along lines similar to GertArnold's answer below, before I knew about the _dbContext.Set<T> all he highlights, I implemented this method on my context class to get sets of a specific type:

public IEnumerable<DbSet<T>> GetDbSetsByType<T>() where T : class
{
    //var flags = BindingFlags.Public | BindingFlags.DeclaredOnly | BindingFlags.Instance;
    var props = GetType().GetProperties()
        .Where(p => p.PropertyType.IsGenericType && p.PropertyType.Name.StartsWith("DbSet"))
        .Where(p => p.PropertyType.GetGenericArguments().All(t => t == typeof(T)));
    return props.Select(p => (DbSet<T>)p.GetValue(this, null));
}

解决方案

Some generalization is possible by using

var dbSet = _dbContext.Set<T>

and putting most of your method in a method with a generics type parameter.

However, there should be a switch somewhere to decide which type should be specified and which type to create, because I think the type is supplied as a property of the model (is it?). So it probably won't really look elegant, but probably be a lot shorter, with DRY-er code.

这篇关于如何推广使用DbSet&LT; TEntity&GT;一的DbContext成员?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆