c# – 在导航属性实体框架上正确使用接口
我正在开发一个应用程序,它可以使用实体框架和Devart连接到多个类似的数据库.我已经通过创建我的EF模型实现的一些接口并且它工作正常,但是我遇到了性能问题,
采用以下接口 public interface IEventBookEntry { int EntryId { get;set;} int EventBookId {get;set;} bool Flagged {get;set; IEntry Entry {get;set;} } 和 public Interface IEntry { int EntryId {get;set;} DateTime EntryTimestamp {get;set;} ICollection<IEventBookEntry> EventBookEntries {get;set;} } 我的两个实体模型(连接到不同的数据库)实现了上述接口. 这意味着我可以在我的BLL层中编写查询,这些查询可以针对任一实体模型运行,很棒! 我们采用以下Linq方法查询: var eventBookEntries = new EventBookRepository().GetList(eb => eb.EventBookId == 123 && eb.Entry.EntryTimestamp > DateTime.Now.AddDays(-3)); 上面的代码获取eventBookId == 123的所有eventbook条目,并且条目的时间戳在过去3天内. 为了完整性,这里是eventBookRepository中“GetList”方法的细节 public IList<IEventBookEntry> GetList(Func<IEventBookEntry,bool> where,params Expression<Func<IEventBookEntry,object>>[] navigationProperties) { return new EventBookEntities().EventBookEntries.Where(where).ToList(); } 你会期望在幕后生成的sql是这样的 SELECT Extent1.EntryId,Extent1.EventBookId,Extent1.Flagged FROM EventBookEntries Extent1 INNER JOIN Entries Extent2 ON Extent1.EntryId = Extent2.EntryId WHERE Extent1.EventBookId = 123 AND Extent2.EntryTimestamp > 22/01/2016 不幸的是,发生的事情是我们没有获得带有条目连接的单个查询,而是我们得到一个查询,它检索所有EventBookEntries,其中EventBookId = 123,然后返回每行查询获得每个条目. SELECT Extent1.EntryId,Extent1.Flagged FROM EventBookEntries Extent1 WHERE Extent1.EventBookId = 123 SELECT Extent1.EntryId,Extent1.EntryTimestamp FROM Entries Extent1 WHERE Extent1.EntryId = :EntityKeyValue1 所以看起来在使用基于接口类型的导航属性生成查询时会出现问题, 更新 我现在已经改为使用一个模型的Code First Entity Framework来删除所有的烟雾和镜子.不幸的是,我得到完全相同的行为. 这是我的模特 [Table("ENTRIES")] public class Entry { public Entry() { EventbookEntries = new List<EventbookEntry>(); } [Key,Column("ENTRY_ID",Order = 1)] public long EntryId { get; set; } [Column("ENTRY_TIMESTAMP")] public DateTime EntryTimestamp { get; set; } [ForeignKey("EntryId")] public virtual ICollection<EventbookEntry> EventbookEntries {get;set;} } 和 [Table("EVENT_BOOK_ENTRIES")] public class EventbookEntry { [Key,Order = 1)] public long EntryId { get; set; } [Key,Column("EVENT_BOOK_ID",Order = 2)] public long EventbookId { get; set; } [ForeignKey("EntryId")] public virtual Entry Entry { get; set; } } 我也创建了一个Db 所以现在我只是直接使用dbContext并更改我的数据库提供程序,这是一种享受,但我仍然得到相同的行为! 我的DbContext有2个DbSet /// <summary> /// Gets or sets the entries. /// </summary> /// <value>The entries.</value> public DbSet<Entry> Entries { get; set; } /// <summary> /// Gets or sets the eventbook entries. /// </summary> /// <value>The eventbook entries.</value> public DbSet<EventbookEntry> EventbookEntries { get; set; } 这是我的linq方法查询 var start = DateTime.Now.AddDays(-20); var eventBookId = 124; var eventbookEntries = new EventBookContext().EventbookEntries.Where(eb=> eb.EventbookId == eventBookId && eb.Entry.EntryTimestamp > start).ToList(); 我的问题是如何在导航属性上实现接口,以确保实体框架将在查询中使用内部联接而不是上面显示的行为? 谢谢 任性 解决方法
您可以使用Fluent API使用关系(
http://www.entityframeworktutorial.net/code-first/configure-one-to-many-relationship-in-code-first.aspx)
在你的DbContext中: protected override void OnModelCreating(DbModelBuilder modelBuilder) { //one-to-many modelBuilder.Entity<Entry>() .HasRequired<EventbookEntry>(ev=> ev.EntryId ) .WithMany(ent => ent.EventbookEntries); } (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |