c# - 具有 Entity Framework 的单例 : Will Queries run multiple times?

标签 c# entity-framework-4

使用诸如...的模型

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.Entity.ModelConfiguration;
using System.Data.Entity;
using System.Data.Entity.Infrastructure;
using System.ComponentModel.DataAnnotations;

namespace Singleton
{
    public class Program
    {
        public static void Main(string[] args)
        {
            var builder = new ModelBuilder();

            builder.Configurations.Add(new TemplateConfiguration());
            builder.Configurations.Add(new UserConfiguration());
            builder.Configurations.Add(new UnitConfiguration());
            builder.Configurations.Add(new AttributeConfiguration());

            var model = builder.CreateModel();

            using (var context = new SampleDataContext(model))
            {
                bool updating = true;
                if (updating)
                {
                    var units = new List<Unit>
                {
                    new Unit{ Name = "Unit1" },
                    new Unit{ Name = "Unit2" }
                };

                    units.ForEach(x => { context.Units.Add(x); });
                    context.SaveChanges();

                    var templates = new List<Template>
                {
                    new Template{
                        Name = "Default",
                        Attributes = new List<Attribute>
                        {
                            new Attribute
                            {
                                Unit = context.Units.Single( i => i.Name == "Unit1" )
                            }
                        }
                    }
                };

                    templates.ForEach(x =>
                    {
                        context.Templates.Add(x);
                    });
                    context.SaveChanges();
                    var users = new List<User>
                {
                    new User
                    {
                        Name = "Stacey"
                    },
                    new User
                    {
                        Name = "Daniel"
                    },
                    new User
                    {
                        Name = "Derek"
                    }
                };

                    users.ForEach(x => { context.Users.Add(x); });
                    context.SaveChanges();

                    updating = !updating; // stop updating
                }

                if (!updating)
                {
                    Single.Instance = context.Templates.Single(i => i.Name == "Default");
                }

                foreach (User user in context.Users)
                {
                    Console.WriteLine(user.Template.Name); // does template requery?
                }
            }
        }
    }
    public class Template
    {
        public virtual int Id { get; set; }
        public virtual string Name { get; set; }
        public virtual ICollection<Attribute> Attributes { get; set; }
    }

    public class TemplateConfiguration : EntityConfiguration<Template>
    {
        public TemplateConfiguration()
        {
            HasKey(k => k.Id);
            Property(k => k.Id).IsIdentity();
            Property(k => k.Name);

            //// map the collection entity
            HasMany(k => k.Attributes).WithRequired()
                .Map("template.attributes",
                    (template, attribute) => new
                    {
                        Template = template.Id,
                        Attribute = attribute.Id
                    });

            MapSingleType(c => new
            {
                c.Id,
                c.Name
            }).ToTable("templates");
        }
    }

    public class User
    {
        public virtual int Id { get; set; }
        public virtual string Name { get; set; }

        [StoreGenerated(StoreGeneratedPattern.None)]
        public Template Template { get { return Single.Instance; } }
    }

    public class UserConfiguration : EntityConfiguration<User>
    {
        public UserConfiguration()
        {
            HasKey(k => k.Id);
            Property(k => k.Id).IsIdentity();
            Property(k => k.Name);

            MapSingleType(c => new
            {
                c.Id,
                c.Name
            }).ToTable("users");
        }
    }

    public class Unit
    {
        public virtual int Id { get; set; }
        public virtual string Name { get; set; }
    }

    public class UnitConfiguration : EntityConfiguration<Unit>
    {
        public UnitConfiguration()
        {
            HasKey(k => k.Id);
            Property(k => k.Id).IsIdentity();
            Property(k => k.Name);

            MapSingleType(c => new
            {
                c.Id,
                c.Name
            }).ToTable("units");
        }
    }

    public class Attribute
    {
        public virtual int Id { get; set; }
        public Unit Unit { get; set; }
    }

    public class AttributeConfiguration : EntityConfiguration<Attribute>
    {
        public AttributeConfiguration()
        {
            HasKey(k => k.Id);
            Property(k => k.Id).IsIdentity();
            // Initialize the Statistic
            HasRequired(k => k.Unit);

            // map the data type to the context so that it can be queried.
            MapHierarchy(c => new
            {
                c.Id,
                Unit = c.Unit.Id
            }).ToTable("attributes");
        }
    }
    public class Single
    {
        public static Template Instance;
    }

    public class SampleDataContext : DbContext
    {
        public SampleDataContext(DbModel model)
            : base(model)
        {
            this.ObjectContext.ContextOptions.LazyLoadingEnabled = true;
        }

        protected override void OnModelCreating(ModelBuilder modelBuilder)
        {
            base.OnModelCreating(modelBuilder);
        }

        public DbSet<Template> Templates { get; set; }
        public DbSet<User> Users { get; set; }
        public DbSet<Unit> Units { get; set; }
        public DbSet<Attribute> Attributes { get; set; }
    }
}

如果我将 Singleton.Instance 分配给来自 DataContext 的查询,然后将 Singleton.Instance 分配给代码中的其他对象,SQL 会运行一次,还是每次被访问时运行?谁能帮我看看这个模式是否会节省一些 SQL?

最佳答案

从 context.SomeQuery 中,您几乎肯定只是返回某种可查询对象或其他可迭代对象(我不确定您的示例是否反射(reflect)了您的 EF 解决方案的实际架构,我认为有些元素是为了简洁)。因此,每次访问此单例时,您都将再次迭代它(运行查询)。

我建议您使用围绕 4.0 缓存的简单内存,尝试 this .

关于c# - 具有 Entity Framework 的单例 : Will Queries run multiple times?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/3623971/

相关文章:

c# - 为什么我有时需要添加 Nuget 依赖项,即使我的项目没有直接使用它们?

c# - 如何在云中托管桌面应用程序?

c# - 使用 ASp.net MVC3 插入数据库后如何显示类似 "successfully Inserted"的警告消息

.net - 如何在连接字符串中设置 Entity framework 4 CommandTimeout?

c# - WPF : Binding a combo-box to an enum property of a class object?

c# - 无法检索登录后添加的声明

c# - 为什么我无法访问另一个表单上的文本框?

entity-framework - Entity Framework 表继承

sql - 使用的SQL Server版本不支持datetime2数据类型?

ASP.NET MVC 3、Entity Framework 4。更新与许多相关的实体