如何从文本框中为Linq提供表名

时间:2017-12-06 12:11:06

标签: c# sql linq

我想将文本框中的表名提供给Linq:

      StudentDatabaseEntities empl = new StudentDatabaseEntities();

        var query = from g in empl.Teachers
                    where g.id == 1
                    select new
                    {
                        Teacher_Id = g.tech_id,
                        Teacher_Name = g.username,
                        Teach_password = g.password,
                        Teacher_contact = g.contact,
                        Teacher_secret = g.secret,

                        //Administrator_Id = g.Administrator.id,

                        Administrator_Name = g.Administrator.username,
                        Administrator_password=g.Administrator.password,
                        Administrator_contact=g.Administrator.contact,
                        Administrator_secret=g.Administrator.secret
                        //etc...
                    };
        dataGridView1.DataSource = query.ToList();

在这个例子中,我想从textbox而不是Teacher中提供表名。 有可能吗?

2 个答案:

答案 0 :(得分:0)

你不能以这种方式违反类型安全是没有意义的:

from g in myTextbox.Text
where g.id == 1

你打算在文本框中写些什么? " empl.Teachers"

如果我写了#34; empl.Students"或者#34;离开"该怎么办?那你的课程会做什么?

如果你有多个教师集合,你可以这样做:

var teachers = new Dictionary<string, (type of your teacher collection)>();
teachers["empl"] = empl.Teachers;
teachers["empl2"] = empl2.Teachers;

from g in teachers[myTextbox.Text]
where g.id == 1

然后你可以写&#34; empl&#34;或&#34; empl2&#34;在你的文本框中..但是这并没有真正凝聚你期望的&#34;在文本框中编写数据库表名&#34;

答案 1 :(得分:0)

如果要对不同类型使用相同的查询,则要使用的所有类型都应具有您在查询中使用的所有属性。

例如,如果您想与学生进行相同的查询,学生也应该有tech_id,用户名,秘密等。

通常你会使用继承/组合或接口来做到这一点。类似的东西:

interface IPersonData
{
    public int tech_id {get;}
    public string username {get;}
    ...
}
class Teacher : IPersonData {...}
class Student : IPersonData {...}

此外,类StudentDataBaseEntities需要一个函数来根据实体类型选择合适的实体。所以,如果你要求教师......&#34;它应该使用empl.Teachers,如果你要求&#34;学生谁...&#34;它应该使用empl.Students。

如果您使用Entity Framework,则可以使用类DbContext.Set。否则你必须自己创建一个类似的功能。

public static IQueryable<TSource> ToMyData<TSource>(this TSource source)
    where TSource : IPersonData
{
    return source
        .Where(sourceItem => sourceItem.Id == 1)
        .Select(sourceItem => new
        {
             Id = sourceItem.tech_id,
             Name = sourceItem.username,
             ...
        });
}

static IQueryable<TSource> ToMyData<TSource>(this DbContext dbContext)
     where TSource : IPersonData
{
    return dbContext.Set<TSource>().ToMyData();
}

或者如果你想要更多的类型安全:

static IQueryable<TSource> ToMyData<TSource>(this DbContext dbContext)
     where TSource : IPersonData
{
    IQueryable<TSource> sourceData = dbContext.Set<TSource>();
    if (sourceData == null) throw new ...

    return sourceData.ToMyData();
}

用法将:

IQueryable<Student> studentData = myDbContext.ToMyData<Student>();
IQueryable<Teacher> teacherData = myDbContext.TyMyData<Teacher>();

但我的StudentDataBaseEntities不是来自DbContext!

在这种情况下,您必须创建一个类似于DbContext.Set的函数。您确切知道StudentDataBaseEntities支持哪些实体。

在您的StudentDataBaseEntities中。

public IQueryable<TSource> GetTable<TSource>()
     where TSource : IPersonData
{
    return this.GetTable(typeof(TSource))
}

public IQueryable<TSource> GetTable(System.Type type)
{
     if (type == typeof(Teacher)) return this.Teachers;
     else if (type == typeof(Student)) return this.Students;
     ...

     // TODO: improve this code by using a switch statement
     // TODO: search stackoverflow how to do this for a type
}