内联比较有效,但如果我将其包装在一个方法中,LINQ表达式无法被翻译。

20 浏览
0 Comments

内联比较有效,但如果我将其包装在一个方法中,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 DbSet
Articles { 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; } } }

0
0 Comments

问题出现的原因是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表达式封装在方法中时,可能会遇到无法翻译表达式树的问题。为了解决这个问题,可以使用内联比较来替代封装在方法中的表达式。

0