我正在开发一个应用程序,它可以使用实体框架和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层中编写查询,这些查询可以针对任一实体模型运行,很棒!
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(); }
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; }
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); }
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。