使用存储库模式在BAL中左外连接 - null异常

时间:2017-06-28 09:21:43

标签: c# entity-framework repository-pattern

我不太明白为什么以下语法可以直接运行到Entity Framework。

var query = (from c in entitites.car
             join cat in entitites.categories on c.code equals cat.code into categoriesGroup
             from cg in categoriesGroup.DefaultIfEmpty()

             select new CarListModel
             {
                 Car = c,            
                 CategoryDescription = cg == null ? null : cg.Description
             });

var test = query.ToList(); //Success

虽然对我的存储库中的iqueryables执行相同的查询但是" DbIsNullExpression的参数必须引用基元,枚举或引用类型。"存储库使用相同的实体对象。

var queryCars = carRepository.GetIQueryable();
var queryCategory = categoryRepository.GetIQueryable();

var query = (from c in queryCars
             join cat in queryCategory on c.Code equals cat.Code into categories
             from cg in categories.DefaultIfEmpty()

             select new CarListModel
             {
                 Car = c,            
                 CategoryDescription = cg == null ? null : cg.Description
             });

var test = query.ToList(); // Fails!!!

使用存储库模式,如果我将语法更改为

,它确实有效
...
CategoryDescription = cg.Description

但是如果我从List中模拟存储库,那么它就会将Object引用设置为一个对象的实例。

我相信这与物化/非物化数据有关。

.DefaultIfEmpty在这些示例中清楚地返回了不同的结果,我正在考虑重写,如果为空则总是返回NULL。不知道我怎么会这样做。

我们的想法是将业务逻辑隔离到服务层,而不是存储库中。虽然也许加入表格不是"不是" BL,在存储库中很好吗?如何使用这种模式进行复杂连接?

使用存储库是否无法进行IQueryable连接?

更新! 从存储库

添加了GetIQueryable方法的示例
public class Category
{
  Public string Code {get;set;}
  Public string Description {get; set;}
}

public IQueryable<Category> GetIQueryable()
    {
        return (from c in entities.categories
                select new Category
                {
                    Code = c.code,
                    Description = c.descripton

                }).AsQueryable();
    }

1 个答案:

答案 0 :(得分:0)

问题出在这里:

public IQueryable<Category> GetIQueryable()
{
    return (from c in entities.categories
            select new Category
            {
                Code = c.code,
                Description = c.descripton

            }).AsQueryable();
}

您无法在查询中使用new Category,因为Category是您的数据模型类(映射到表)。您有两个选择:

  1. 不使用new重写查询:

    public IQueryable<Category>GetIQueryable()
    {
        return (from c in entities.categories
                select c).AsQueryable();
    }
    
  2. 使用其他DTO对象作为结果:

    class CategoryDto
    {
        public int Code {get;set;}
        public string Description {get;set;}
    }
    
    //...
    
    public IQueryable<CategoryDto> GetIQueryable()
    {
        return (from c in entities.categories
                select new CategoryDto
                {
                    Code = c.code,
                    Description = c.descripton
                }).AsQueryable();
    }