内联比较有效,但如果我将其包装在一个方法中,LINQ表达式无法被翻译。
内联比较有效,但如果我将其包装在一个方法中,LINQ表达式无法被翻译。
完整的源代码在底部,但这里是重点。
如果有任何方法可以避免重复代码x.ArticleId == demo.ArticleId && x.Title == demo.Title
并重用一个源码吗?
Program.cs
using Microsoft.EntityFrameworkCore.Storage; using System.Diagnostics; namespace EntityTest { internal class Program { static void Main(string[] args) { var mydb = new MyDbContext(); var article1 = new Article() { ArticleId = 1234, Title = "First", }; var article2 = new Article() { ArticleId = 5678, Title = "Second", }; var article3 = new Article() { ArticleId = 9012, Title = "Third", }; mydb.Articles.AddRange(article1, article2, article3); mydb.SaveChanges(); var demo = new WebArticle() { ArticleId = 5678, Title = "Second", }; //使用内联代码 if (mydb.Articles.Any(x => (x.ArticleId == demo.ArticleId && x.Title == demo.Title))) { Console.WriteLine("存在"); } else { Console.WriteLine("不存在"); } //使用方法 if (mydb.Articles.Any(x => x.IsSame(demo))) { Console.WriteLine("存在"); } else { Console.WriteLine("不存在"); } } } class WebArticle { public int ArticleId { get; set; } public string Title { get; set; } } }
MyDbContext.cs
using Microsoft.EntityFrameworkCore; using System; using System.Collections.Generic; using System.ComponentModel.DataAnnotations; using System.Linq; using System.Text; using System.Threading.Tasks; namespace EntityTest { internal class MyDbContext:DbContext { protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder) { optionsBuilder.UseInMemoryDatabase("memory"); base.OnConfiguring(optionsBuilder); } public DbSetArticles { get; set; } public DbSet ArticleImages { get; set; } } class Article { [Key] public int Id { get; set; } public int ArticleId { get; set; } public string Title { get; set; } public bool IsSame(WebArticle other) { return (ArticleId == other.ArticleId && Title == other.Title); } } class ArticleImage { public int Id { get; set; } public int ArticleId { get; set; } public string Url { get; set; } } }
问题出现的原因是LINQ表达式无法翻译成方法。解决方法是使用内联比较而不是将其封装在方法中。
在给定的代码示例中,问题出现在使用LINQ表达式封装在一个方法中时。具体来说,当尝试使用LINQ表达式`mydb.Articles.Any(Article.IsSame(demo))`时,会出现问题。在`Article`类中,`IsSame`方法被封装在一个静态方法中,该方法返回一个表达式树,用于比较两个`Article`对象的属性是否相同。
然而,LINQ无法将这个表达式树翻译成可执行的SQL查询,因此会导致错误。为了解决这个问题,可以使用内联比较来替代封装在方法中的表达式。通过直接在LINQ查询中使用内联比较,可以绕过无法翻译表达式树的问题。
具体来说,在给定的代码示例中,可以将`mydb.Articles.Any(Article.IsSame(demo))`修改为`mydb.Articles.Any(x => x.ArticleId == demo.ArticleId && x.Title == demo.Title)`。这样就可以避免使用封装在方法中的表达式,从而解决了问题。
总之,当尝试将LINQ表达式封装在方法中时,可能会遇到无法翻译表达式树的问题。为了解决这个问题,可以使用内联比较来替代封装在方法中的表达式。