如果要在编译时绑定类型,可以将类型作为泛型参数传递,并使用这种类型的方法:
public DbSet<T> GetDataSource<T>()
{
var targetType = typeof(DbSet<T>);
return _db
.GetType()
.GetMethods()
.Where( m => m.ReturnType == targetType)
.Single()
.Invoke(_db, null) as DbSet<T>;
}
它是如何工作的?好吧,我们不知道返回被请求实体的方法的名称,但我们知道返回类型必须是DbSet<T>。因此,我们扫描 DatabaseContext 以查找任何返回该类型的方法,然后调用它。这假定只有一种方法具有该返回类型。
如果您需要真正的运行时绑定(您不能提供<T> 参数),您可以使用这种方法。请注意,返回类型只是一般的IEnumerable,因为如果在编译时不知道,则不能有特定的返回类型。如果需要,您可以随时将其转换回 DbSet<T>。
public IEnumerable GetDataSource(Type type)
{
var targetType = typeof(DbSet<>).MakeGenericType(new Type[] { type });
return _db
.GetType()
.GetMethods()
.Where( m => m.ReturnType == targetType)
.Single()
.Invoke(_db, null) as IEnumerable;
}
这是一个完整的例子。请注意,我删除了 EF 对象,但此示例仍应适用于真实的 DbSet 和 DatabaseContext。
using System;
using System.Linq;
using System.Collections;
using System.Collections.Generic;
public class Program
{
public class DbSet<T> : List<T>
{
}
public class User
{
public string Name { get; set; }
public override string ToString()
{
return "User " + Name;
}
}
public class Transaction
{
public decimal Amount { get; set; }
public override string ToString()
{
return "Transaction " + Amount.ToString("0.00");
}
}
public class DatabaseContext
{
public DbSet<User> GetUsers()
{
return new DbSet<User>()
{
new User { Name = "Bob" },
new User { Name = "Alice" }
};
}
public DbSet<Transaction> GetTransactions()
{
return new DbSet<Transaction>()
{
new Transaction { Amount = 12.34M },
new Transaction { Amount = 56.78M }
};
}
}
public class HelperClass
{
private readonly DatabaseContext _db;
public HelperClass(DatabaseContext db)
{
_db = db;
}
public DbSet<T> GetDataSource<T>()
{
var targetType = typeof(DbSet<T>);
return _db
.GetType()
.GetMethods()
.Where( m => m.ReturnType == targetType)
.Single()
.Invoke(_db, null) as DbSet<T>;
}
public IEnumerable GetDataSource(Type type)
{
var targetType = typeof(DbSet<>).MakeGenericType(new Type[] { type });
return _db
.GetType()
.GetMethods()
.Where( m => m.ReturnType == targetType)
.Single()
.Invoke(_db, null) as IEnumerable;
}
}
public static void Main()
{
var helperClass = new HelperClass(new DatabaseContext());
foreach (var u in helperClass.GetDataSource<User>())
{
Console.WriteLine(u);
}
foreach (var t in helperClass.GetDataSource(typeof(Transaction)))
{
Console.WriteLine(t);
}
}
}
输出:
User Bob
User Alice
Transaction 12.34
Transaction 56.78
Full code on DotNetFiddle