gpt4 book ai didi

c# - 在导航属性 Entity Framework 上正确使用接口(interface)

转载 作者:行者123 更新时间:2023-11-30 12:57:19 29 4
gpt4 key购买 nike

我正在开发一个应用程序,它可以使用 Entity Framework 和 Devart 连接到多个类似的数据库。我通过创建我的 EF 模型实现的一些接口(interface)来完成此操作并且工作正常,但是我遇到了性能问题,

获取以下接口(interface)

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;}

}

我的两个实体模型(连接到不同的数据库)实现了上述接口(interface)。

这意味着我可以在我的 BLL 层中编写查询,该层可以针对任一实体模型运行,太棒了!

让我们采用以下 Linq 方法查询:

   var eventBookEntries = new EventBookRepository().GetList(eb => eb.EventBookId == 123 && eb.Entry.EntryTimestamp > DateTime.Now.AddDays(-3));

上面的代码获取了所有事件簿条目,其中 eventBookId == 123 并且条目的时间戳在过去 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.EventBookId, Extent1.Flagged 
FROM EventBookEntries Extent1
WHERE Extent1.EventBookId = 123


SELECT Extent1.EntryId, Extent1.EntryTimestamp
FROM Entries Extent1
WHERE Extent1.EntryId = :EntityKeyValue1

所以看起来使用基于接口(interface)类型的导航属性生成查询时有问题,

更新

我现在已更改为具有一个模型的 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, Column("ENTRY_ID", 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();

我的问题是如何在导航属性上实现接口(interface),以确保 Entity Framework 将在查询中使用内部联接而不是上面展示的行为?

谢谢

任性

最佳答案

您可以使用 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);
}

关于c# - 在导航属性 Entity Framework 上正确使用接口(interface),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34991209/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com