Linq 2 Sql - 除非在控制器内完成查询,否则存储库不起作用

Posted

技术标签:

【中文标题】Linq 2 Sql - 除非在控制器内完成查询,否则存储库不起作用【英文标题】:Linq 2 Sql - Repository isn't working unless query is done inside controller 【发布时间】:2011-05-17 03:43:51 【问题描述】:

我真的很难理解我面临的问题。我有一个非常简单的存储库,代码如下:

public class ProductRepository : IProductRepository

    private Table<Product> productTable;

    public Product GetProductById(int id)
    
         return productTable.Where(p => p.ProductId == id).Single();
    

    public IQueryable<Product> GetProducts()
    
        return productTable;
    
 

我有一个名为 AddToCart() 的控制器。上面的存储库类通过 DI 传递到控制器中。我将 productId 传递给此控制器,然后调用存储库方法。问题是当 Product 确实存在时返回一个空值。

    public void AddToCart(int productId)
    
        //Returns Null value
        Product product = productRepository.GetProductById(productId);
        ...
    

我认为问题可能是我需要 IQueryable&lt;&gt; 在我要返回的班级周围。我还以各种方式修改了我的 AddToCart 方法以尝试使其正常工作。

public IQueryable<Product> GetProductById(int id)

    return productTable.Where(p => p.ProductId == id);


public void AddToCart(int productId)

    //Throws error / Returns Null value
    Product product = productRepository.GetProductById(productId).Single();
    //Returns Null value
    Product product = productRepository.GetProductById(productId).FirstOrDefault();

但是,以下工作,我没有理由!它基本上是相同的代码,只是在控制器中完成。有人有想法么? :/

    public void AddToCart(int productId)
    
        Product product = productRepository.GetProducts().FirstOrDefault(p => p.ProductId == productId);
    

【问题讨论】:

productTable 是如何/何时在ProductRepository 中创建的? productRepository的实例是如何创建的? @contactmatt,你使用什么 DI/IOC 框架?我相信您的问题主要与此有关,即在一个用例中,框架正在正确注入 productTable,而在其他情况下,则不是! 您的 Table 是否被 Ninject 注入?如果是这样,我们可以看到绑定吗? 我将在这里发表与您的其他问题相同的评论:如果您设置context.Log = Console.Out;,它是否会为每个查询显示相同的 SQL? @Gabe,我会检查的。我目前不在 Visual Studio 中对其进行测试,但是 context.Log 写在哪里?到 Visual Studio 控制台? 【参考方案1】:

我想知道您的依赖注入是否存在问题。您正在使用 .Single() ,根据文档,如果集合中没有一个项目满足您的条件,它将引发异常。

我会尝试在不使用依赖注入的情况下实现它,看看你是否得到相同的结果。您还可以尝试直接从 GetProductById 方法(而不是从数据库中提取)实例化和返回产品项,以排除您的 DI 发生的任何异常情况。

【讨论】:

【参考方案2】:

如果没有更多信息,很难看出问题所在。

    GetProductById() 如何返回 null? Single() 不允许返回空值,如果没有项目或返回多个项目,则会抛出 InvalidOperationException。 GetProducts() 有何不同之处?查看您的代码,应该没有问题。

当你尝试这个时会发生什么?

public class ProductRepository : IProductRepository
      
    private Table<Product> productTable;    

    public Product GetProductById(int id)             
        return GetProducts().Where(p => p.ProductId == id).Single();    
        

    public IQueryable<Product> GetProducts()            
      return productTable;    
     

附带说明,如果您确定您的收藏中只有一个项目,则应避免使用 Single()。 Single 将始终遍历您的整个集合。 First() 在这方面效率更高。

【讨论】:

GetProducts().Single(p =&gt; p.ProductId == id); 会不会更直截了当? 找出问题所在很重要。我的方法实际上是一种创可贴的解决方案,它应该告诉我们该方法是否做得比我们看到的更多。

以上是关于Linq 2 Sql - 除非在控制器内完成查询,否则存储库不起作用的主要内容,如果未能解决你的问题,请参考以下文章

如何在 LINQ SQL C# 中返回动态周数?

如何将带有内连接的 sql 查询转换为 linq lambda 表达式?

SQL 子查询练习

如何在sql 中控制查询出来的其中一项数据在前端不能被传递

Linq to SQL 的连表查询(转)

在 ASP.NET MVC 中向控制器传递多个参数;此外,在 LINQ-to-SQL 中生成动态查询