Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/wordpress/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 一般从实体框架返回一个项_C#_Generics_Entity Framework 4 - Fatal编程技术网

C# 一般从实体框架返回一个项

C# 一般从实体框架返回一个项,c#,generics,entity-framework-4,C#,Generics,Entity Framework 4,我遇到过这样一种情况:网站可以基于字符串从我的数据库中请求数据(别担心,我在防范SQL注入)。出于各种原因,我希望有一个方法返回用户期望的对象(从EF返回)(最终通过部分页面返回) 我是这样想的: public <GenericType?> GetObject(int id, string typeName) { switch(typeName) { case "Type1": return db.Type1s.SingleOrDefault(t =>

我遇到过这样一种情况:网站可以基于字符串从我的数据库中请求数据(别担心,我在防范SQL注入)。出于各种原因,我希望有一个方法返回用户期望的对象(从EF返回)(最终通过部分页面返回)

我是这样想的:

public <GenericType?> GetObject(int id, string typeName) {
  switch(typeName) {
    case "Type1":
      return db.Type1s.SingleOrDefault(t => t.TypeID == id);
    case "Type2":
      return db.Type2.SingleOrDefault(t => t.TypeID == id);
    default:
      return null;
  }
}
object obj = GetObject(257, "Type1");
public IMyInterface GetObject(int id, string typeName) {
    switch(typeName) {
        case "Type1":
            return (IMyInterface)db.Type1s.SingleOrDefault(t => t.TypeID == id);
        case "Type2":
            return (IMyInterface)db.Type2.SingleOrDefault(t => t.TypeID == id);
        default:
            return null;
    }
}
IMyInterface intf = GetObject(257, "Type1");
intf.DoSomethingHelpful();
public GetObject(int-id,string-typeName){
开关(类型名称){
案例“类型1”:
返回db.Type1s.SingleOrDefault(t=>t.TypeID==id);
案例“类型2”:
返回db.Type2.SingleOrDefault(t=>t.TypeID==id);
违约:
返回null;
}
}
有可能这样做吗?(我试图避免的是必须先执行switch语句,然后调用特定的存储库方法,因为这样我就必须重复代码并执行多次。)

CreateQuery
可能就是您所需要的

是否有任何方法可以获得所有可能要传递的类型,以便与具有此TypeID属性的特定接口协作?如果是,那么:

    public T GetResult<T>(int id, string typeName) where T : IClassWithTypeID {
        YourEntities db = new YourEntities();
        var result = db.CreateQuery<T>(String.Format("[{0}]", typeName));

        return result.Single(t => t.TypeID == id);
    }
public T GetResult(int-id,string-typeName),其中T:IClassWithTypeID{
YourEntities db=新建YourEntities();
var result=db.CreateQuery(String.Format(“[{0}]”,typeName));
返回result.Single(t=>t.TypeID==id);
}

实际上,任何类型的通用报表生成器/查询执行器/等都可以更好地使用直接SQL查询,而不是尝试将动态逻辑融入EF或LINQ。

怎么样

    public T GetResult<T>(int id, string typeName) {
        AccrualTrackingEntities db = new AccrualTrackingEntities();
        var result = db.CreateQuery<T>(String.Format("[{0}]", typeName));

        var param = Expression.Parameter(typeof(T));

        var lambda = Expression.Lambda<Func<T, bool>>(
            Expression.Equal(
                Expression.Property(param, "TypeID"),
                Expression.Constant(id)),
            param);

        return result.Single(lambda);
    }
public T GetResult(int-id,string-typeName){
AccountalTrackingEntities db=新的AccountalTrackingEntities();
var result=db.CreateQuery(String.Format(“[{0}]”,typeName));
var param=表达式参数(typeof(T));
var lambda=表达式.lambda(
表达式。相等(
Expression.Property(param,“TypeID”),
表达式.常量(id)),
参数);
返回结果。单个(λ);
}

我想手动将表达式树串在一起并不像我想象的那么难。

考虑调用此方法时的情况……大概会是这样:

public <GenericType?> GetObject(int id, string typeName) {
  switch(typeName) {
    case "Type1":
      return db.Type1s.SingleOrDefault(t => t.TypeID == id);
    case "Type2":
      return db.Type2.SingleOrDefault(t => t.TypeID == id);
    default:
      return null;
  }
}
object obj = GetObject(257, "Type1");
public IMyInterface GetObject(int id, string typeName) {
    switch(typeName) {
        case "Type1":
            return (IMyInterface)db.Type1s.SingleOrDefault(t => t.TypeID == id);
        case "Type2":
            return (IMyInterface)db.Type2.SingleOrDefault(t => t.TypeID == id);
        default:
            return null;
    }
}
IMyInterface intf = GetObject(257, "Type1");
intf.DoSomethingHelpful();
我想不出使返回值的类型更具体的方法,因为EF中的对象没有公共基类,也没有实现公共接口。当然,您可以让他们实现这样一个接口(正如Adam所建议的,尽管目的不同),然后像这样重写您的方法:

public <GenericType?> GetObject(int id, string typeName) {
  switch(typeName) {
    case "Type1":
      return db.Type1s.SingleOrDefault(t => t.TypeID == id);
    case "Type2":
      return db.Type2.SingleOrDefault(t => t.TypeID == id);
    default:
      return null;
  }
}
object obj = GetObject(257, "Type1");
public IMyInterface GetObject(int id, string typeName) {
    switch(typeName) {
        case "Type1":
            return (IMyInterface)db.Type1s.SingleOrDefault(t => t.TypeID == id);
        case "Type2":
            return (IMyInterface)db.Type2.SingleOrDefault(t => t.TypeID == id);
        default:
            return null;
    }
}
IMyInterface intf = GetObject(257, "Type1");
intf.DoSomethingHelpful();
那么您的呼叫代码如下所示:

public <GenericType?> GetObject(int id, string typeName) {
  switch(typeName) {
    case "Type1":
      return db.Type1s.SingleOrDefault(t => t.TypeID == id);
    case "Type2":
      return db.Type2.SingleOrDefault(t => t.TypeID == id);
    default:
      return null;
  }
}
object obj = GetObject(257, "Type1");
public IMyInterface GetObject(int id, string typeName) {
    switch(typeName) {
        case "Type1":
            return (IMyInterface)db.Type1s.SingleOrDefault(t => t.TypeID == id);
        case "Type2":
            return (IMyInterface)db.Type2.SingleOrDefault(t => t.TypeID == id);
        default:
            return null;
    }
}
IMyInterface intf = GetObject(257, "Type1");
intf.DoSomethingHelpful();

当然,我对您的调用代码的猜测可能有点离谱。

我很想推荐一个动态解决方案,但动态对象不能分派扩展方法(如
IEnumerable.Where
),表达式树也不能有动态操作。请看一看,以前称为“ADO.NET数据服务”.Adam-我相信这可以通过使用表达式树来实现…@肉体-我知道你可以,但我不知道这有多容易。我需要深入了解表达式树。我不是那个否决你的人——尽管我当然不同意动态SQL比通用解决方案更可取。@Adam:我没说它更可取。但我已经在这条路上走了好几次了。为了完成任务,你不断地与语言斗争。我只是想说,实际上这可能是错误的方法。是的,很公平。如果他不能像我建议的那样在那里获得一个接口,那么一些SQL可能比EF大师建议的任何巫毒都要好+1@Adam:谢谢。我把它改写得稍微好一点,并缓和了我的情绪:)你可能是对的,但他的用例非常简单,就像手工编写的sql一样高效。你能从
T
中确定类型名是什么并删除一个参数吗?也许-
typeof(T)。name
将返回(万一是)“Invoice”虽然EF需要ObjectSet的名称,也就是“Invoices”,但如果您的所有类型都可以通过在S上加上大头钉来正确地进行复数,那么您应该能够。但是请注意,如果您有Person类型的实体,则集合名称可能是People。在这种情况下,您可以使用System.Data.entity.Design.PluralizationServices.PluralizationService。这就是EF用来创建你的类型的复数形式。这其实并不重要,但一般来说我真的不喜欢魔术弦。