在dbcontext中传递泛型类名

时间:2014-11-18 01:29:00

标签: c# vb.net entity-framework dbcontext

我的实体上下文文件代码:

public partial class MyDbContext : DbContext
{
    //dbset 1
    public DbSet<Customer> Customers { get; set; }

    //dbset 2
    public DbSet<Order> Orders { get; set; }
}

Class Shipments有一个方法GetCustomerName

public class Shipments
{
    public string GetName(object caller, System.Data.Entity.DbSet objectContext)
    {
        //This one passes.

        IQueryable<Customer> myCustomer = from p in objectContext
                                          select p where p.Id=1; //get customer name

        //This one fails
        IQueryable<caller.GetType()> myCustomer = from p in objectContext
                                                  select p where p.Id=1; //get customer name
    }
}

问题:我想在那里删除类Customer的硬编码,而是通过将类名作为参数传递来调用此方法?

我该如何实现?在这种情况下,caller.GetType().Name对我不起作用。

GetName(Order, mydbContext);
GetName(Customer, mydbContext);

两者都应该使用相同的代码(尝试制作通用代码,我不知道如何将其转换为通用代码)。任何帮助都会很棒。感谢。

2 个答案:

答案 0 :(得分:2)

我没有看到传递object参数只是为了获得它的类型。您可以使用泛型:

public string GetName<T>(DbSet objectContext) where T : BaseEntity {
    IQueryable<T> myCustomer = from p in objectContext
                               select p where p.Id = 1;
    //Get the name
    //Return the name
}

请注意,我添加了T的约束,以从BaseEntity扩展。

然后,您的所有实体都应该从这个抽象类扩展(应该包含属性IdName以获取名称)。

然后,您将能够检索Customer个实体的名称,甚至是Order个实体的名称:

string customerName = GetName<Customer>(context);
string orderName = GetName<Order>(context);

如果只有您的Customer实体拥有该属性Name,那么根本不使用泛型,您最好明确定义该类型:

public string GetName(context) {
    IQueryable<Customer> customer = from p in context
                                    select p where p.Id = 1;
    //Get the name
    //Return the name
}

答案 1 :(得分:2)

像许多人一样,包括我自己,你没有看到数据类型和Type类实例之间的区别。数据类型是在编译时已知的。当您致电GetType时,您获得的是数据类型为Type的对象。它包含有关数据类型的信息,但它本身不是数据类型。

您需要做的是使您的GetName方法也是通用的:

public string GetName<T>(T caller, System.Data.Entity.DbSet objectContext)
{
    IQueryable<T> myEntity = from p in objectContext
                             select p where p.Id=1; //get customer name
}

为了能够做到这一点,编译器必须知道类型T实际上具有Id属性。这意味着必须将T约束为声明Id属性的特定基类或接口。对于自动生成的EF类,接口是您唯一的选择。

您的代码还存在其他问题,但这涵盖了您实际要问的内容。