Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/linq/3.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# 你能将OOP应用于Linq投影吗? 使用 VisualStudio2010 .Net框架4 C Linq到实体 问题_C#_Linq_Oop_Linq To Entities_Design Principles - Fatal编程技术网

C# 你能将OOP应用于Linq投影吗? 使用 VisualStudio2010 .Net框架4 C Linq到实体 问题

C# 你能将OOP应用于Linq投影吗? 使用 VisualStudio2010 .Net框架4 C Linq到实体 问题,c#,linq,oop,linq-to-entities,design-principles,C#,Linq,Oop,Linq To Entities,Design Principles,我希望能够将面向对象的原则(如DRY和SOLID)应用于一些Linq投影。通过编译的查询或传递的参数,到目前为止,我可以成功地将这些应用到Linq的其余部分,只是不能应用到投影中 如果这不可能,请让我知道,我必须选择下面描述的备选解决方案之一,如果可能,那么如何,或者如果我遗漏了什么,并且有另一个备选实现可以满足目标 细节 在较高的层次上,我希望能够通过标准Linq查询或CompiledQuery动态控制Linq投影中使用的类型。我在示例和实际代码中使用Linq to实体,但是这个问题应该适用于

我希望能够将面向对象的原则(如DRY和SOLID)应用于一些Linq投影。通过编译的查询或传递的参数,到目前为止,我可以成功地将这些应用到Linq的其余部分,只是不能应用到投影中

如果这不可能,请让我知道,我必须选择下面描述的备选解决方案之一,如果可能,那么如何,或者如果我遗漏了什么,并且有另一个备选实现可以满足目标

细节 在较高的层次上,我希望能够通过标准Linq查询或CompiledQuery动态控制Linq投影中使用的类型。我在示例和实际代码中使用Linq to实体,但是这个问题应该适用于核心Linq

下面是一些简单的例子,它们不是动态的,不能解决问题。它们被固定为对每种类型始终使用FooUser。我希望能够动态控制在投影中创建的用户类型,所有这些都将基于一个公共的IUser接口。这将或可能类似于我如何控制查询过滤器的类型

替代解决方案 我试图遵循干燥、坚实的原则,同时也试图避免使用枚举来处理典型的代码气味。然而,在我所有的尝试和研究中,我似乎不得不采用以下解决方案之一

为每种类型实现一个查询 除了 他们筛选的类型和 用于投影。而这 干爽和OCP,我可以 将其封装在单个 上课并让他们保持紧密联系 如有疑问。这将 如果我添加 新类型或如果您查询 数据发生了变化

实现一个具有类型的枚举,并使用一个更通用的用户类,该类的类型作为属性。但是,这将导致我不得不在多个位置使用enum,并引入长case语句来处理它们,这是我希望避免的

我希望不必在不同的邪恶之间做出选择,我希望有一个能够符合所有坚实原则和原则的实现。然而,如果我必须这样做,我想我最终会得到它的第一个版本或一个版本

例子 标准简单Linq查询

using (MyEntities context = new MyEntities())
{
    var results = from u in context.Users
                  where u.UserType == type
                  select new FooUser
                  {
                      Id = u.UserID,
                      Name = u.UserName,
                      Location = u.UserLocation
                  };
}
上述查询的编译版本

private static readonly Func<MyEntities, int, IQueryable<FooUser>> query = CompiledQuery.Compile<MyEntities, int, IQueryable<FooUser>>(
    (context, type) => from u in context.Users
                       where u.UserType == type
                       select new FooUser
                       {
                           Id = u.UserID,
                           Name = u.UserName,
                           Location = u.UserLocation
                       });-

我找到了一种通过标准方法调用实现这一点的方法。我还没有弄清楚如何使用编译的查询,看起来不太可能

我不知道泛型的where语句上的构造函数约束I。这能满足我的需要。我很想用编译后的查询来实现这一点,但我可以很高兴地使用这个解决方案

public IQueryable<IUser> FooMethod<T>(int type) where T : IUser, new()
{
    using (MyEntities context = new MyEntities())
    {
        var results = from u in context.users
                      where u.usertype == type
                      select new T
                      {
                          id = u.UserId,
                          name = u.UserName,
                          location = u.Userlocation
                      };
        return results; 
    }
}

我选择发布一个答案,而不是删除这个问题,原因有两个,一个是为了防止其他人正在寻找类似的东西,这可能会有所帮助。当然,我可能会偏离底线,让人们在事情上打洞,看看我们能想出什么更好的东西,这总是很有趣的。

恐怕我不明白你问的问题。您能指出您希望消除的重复代码吗?重复代码在替代解决方案部分中进行了解释,这正是我试图避免的。示例代码只是为了显示一个查询示例,以便在需要时与之对话。我发布了一个适合我的解决方案,如果你有更好的解决方案,请随意发布。尤其是在编译后的查询中。