初学者有关AsEnumerable()的问题

马修

会员
已加入
2020年8月15日
留言内容
23
编程经验
Beginner
我正在学习EF核心(初学者)课程,有些事情我听不懂。
在下面,您可以找到一些基本的最重要的练习,以了解EF核心和意图。

Student:
public class Student
    {
        public int StudentId { get; set; }
        public string Firstname { get; set; }
        public string Lastname { get; set; }

        public Student(string firstname, string lastname)
        {
            Firstname = firstname;
            Lastname = lastname;
        }
    }

EfTestDbContext:
public class EfTestDbContext : DbContext
    {
        public DbSet<Student> Students { get; set; }

        public EfTestDbContext()
        {
            EfTestInitializer.Initialize(this, true);
        }
        
        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        {
            if (!optionsBuilder.IsConfigured)
            {
                optionsBuilder.UseSqlite("Data Source = EF_TEST.db")
                    .UseLoggerFactory(LoggerFactory.Create(builder => builder.AddDebug()));
            }
        }
    }

EfTestInitializer:
public class EfTestInitializer
    {
        public static void Initialize(EfTestDbContext context, bool dropAndCreateDatabase = false)
        {
            if (dropAndCreateDatabase)
            {
                context.Database.EnsureDeleted();
            }

            if (context.Database.EnsureCreated())
            {
                Seed(context);
            }
        }
        
        private static void Seed(EfTestDbContext context)
        {
            Student s1 = new Student("M", "S");
            Student s2 = new Student("A", "S");

            context.Students.Add(s1);
            context.Students.Add(s2);

            context.SaveChanges();
        }
    }

Irepository:
public interface IRepository
    {
        IEnumerable<Student> ReadAllStudents();
    }

Repository:
 public class Repository : IRepository
    {
        private EfTestDbContext context;

        public Repository()
        {
            context = new EfTestDbContext();
        }

        public IEnumerable<Student> ReadAllStudents()
        {
            return context.Students.AsEnumerable();
        }
    }

Program:
class Program
    {
        private static readonly IRepository Repository = new Repository();
        
        static void Main(string[] args)
        {
            ShowAllStudents();
        }

        private static void ShowAllStudents()
        {
            Console.WriteLine(Repository.CountAllStudents());
        }
    }

在Repository类下的ReadAllStudents方法的主体中,返回带有AsEnumerable的Student DbSet。但是,为什么还要放置AsEnumerable?
即使没有AsEnumerable,它是否已经是Enumerable了?有或没有结果,并且使用的查询是相同的...

谢谢你的协助!
 

金西尼

C#论坛主持人
工作人员
已加入
2011年4月23日
留言内容
3,501
地点
悉尼,澳大利亚
编程经验
10+
I would think that the AsEnumerable call actually limits the functionality available. Yes, the DbSet<Student> does implement IEnumerable<Student> but the class provides much more functionality besides. By calling AsEnumerable, you actually get a different type that provides only the specific functionality of being able to be enumerated. Basically, the caller of that code is limited to ONLY the functionality of IEnumerable<Student> and prevented from accessing the rest of the functionality of DbSet<Student>.
 

跳伞

工作人员
已加入
2019年4月6日
留言内容
2,497
地点
弗吉尼亚州切萨皮克
编程经验
10+
尝试一下您的假设。如果将其取出,它仍然可以编译吗?

If it does work, some people like being explicit, like putting private or this. even when it isn't needed.  :) 但是,认真地讲,开发人员在编写代码时的主要工作是与其他开发人员交流思想-碰巧的是,计算机也可以执行这些思想中体现的步骤。
 

金西尼

C#论坛主持人
工作人员
已加入
2011年4月23日
留言内容
3,501
地点
悉尼,澳大利亚
编程经验
10+
我只是看了看该方法的实现,它实际上什么也没做。它实际上只是一个演员:
C#:
/// <summary>Returns the input typed as <see cref="T:System.Collections.Generic.IEnumerable`1" />.</summary>
/// <param name="source">The sequence to type as <see cref="T:System.Collections.Generic.IEnumerable`1" />.</param>
/// <typeparam name="TSource">The type of the elements of <paramref name="source" />.</typeparam>
/// <returns>The input sequence typed as <see cref="T:System.Collections.Generic.IEnumerable`1" />.</returns>
[__DynamicallyInvokable]
public static IEnumerable<TSource> AsEnumerable<TSource>(
  this IEnumerable<TSource> source)
{
  return source;
}
 

跳伞

工作人员
已加入
2019年4月6日
留言内容
2,497
地点
弗吉尼亚州切萨皮克
编程经验
10+
从可执行代码方面,您不需要它。对于表达意图,它很有用。

It's like making the intentional choice between a for, while, do-while, or a foreach loop. There is something that you want to tell the next person reading the code based on how you write your code.
 
最佳 底部