使用lambda表达式检查表上是否存在产品

时间:2016-01-08 09:59:00

标签: c# entity-framework lambda

我正在使用.NET Framework 4.0和Entity Framework 6.1.3开发C#库。

我有一个变量List<ProductViewModel> viewModel。我想检查一下这个变量上的某些产品是否已存在于PRODUCTS表中。

ProductViewModel声明是:

public class ProductViewModel
{
    public string ProductCode { get; set; }
    public string ProductDescription { get; set; }
}

我测试了这个谓词:

Expression<Func<PRODUCTS, bool>> predicate =
    p => (p.LAW == (byte)LawTypes.Korea) &&
        !viewModel.Any(item => item.ProductCode == p.PRODUCT_CODE);

这一个:

Expression<Func<PRODUCTS, bool>> predicate =
    p => (p.LAW == (byte)LawTypes.Korea) &&
        !viewModel.Select(x => x.ProductCode).Contains(p.PRODUCT_CODE);

当我对两个谓词执行此操作时:

if (_dbSet.Where(predicate).Count() == 0)

我得到以下异常:

  

无法创建类型的常量值   &#39; MyProject.Web.API.Models.ProductViewModel&#39 ;.只有原始类型或   在此上下文中支持枚举类型。

PRODUCTS是:

public class PRODUCTS
{
    public int Id { get; set; }
    public string PRODUCT_CODE { get; set; }
    public string DESCRIPTION { get; set; }
    public byte LAW { get; set; }
}

我该如何解决这个问题?

1 个答案:

答案 0 :(得分:0)

您的问题是,您假设使用expressiontree的linq可以访问您的本地变量viewModel

Expression<Func<PRODUCTS, bool>> predicate =
p => (p.LAW == (byte)LawTypes.Korea) &&
    !viewModel.Any(item => item.ProductCode == p.PRODUCT_CODE);

您将此表达式传递给linq查询,这些查询完全不了解viewModel的含义。

您应该使用ProductViewModel作为foreignKey在ProductProductCode之间建立联系:

public class PRODUCTS
{
public int Id { get; set; }
[ForeignKey("ProductViewModels")]
public string PRODUCT_CODE { get; set; }
public string DESCRIPTION { get; set; }
public byte LAW { get; set; }

public virtual ICollection<ProductViewModel> ProductViewModels {get; set;}
}

然后你可以写下你的表达式:

Expression<Func<PRODUCTS, bool>> predicate =
p => (p.LAW == (byte)LawTypes.Korea) &&
    !p.ProductViewModels.Any();

只要确保你在产品和视图模型之间建立正确的关系,我认为它是一对多的。如果它的数据库是第一个,你必须在数据库中定义你的外键。