这些模型可以在EF7中表示吗?

山姆·尼尔森

我试图将自己项目中另一个程序集中的某些类用作可以使用EF7持久保存的实体,而不是编写一系列对数据库更友好的非常相似的类。

简化的版本如下所示:

interface IMediaFile
{
    string Uri { get; }
    string Title { get; set; }
}
class CMediaFile : IMediaFile
{
    public CMediaFile() { }
    public string Uri { get; set; }
    public string Title { get; set; }
}

//The following types are in my project and have full control over.
interface IPlaylistEntry
{
    IMediaFile MediaFile { get; }
}
class CPlaylistEntry<T> : IPlaylistEntry where T : IMediaFile
{
    public CPlaylistEntry() { }
    public T MediaFile { get; set; }
}

IMediaFile有多种实现,我只展示一种。我的PlaylistEntry类采用一个通用参数来为各种实现启用不同的特征,而我只是使用IPlaylistEntry。

所以我开始像这样建模:

var mediaFile = _modelBuilder.Entity<CMediaFile>();
mediaFile.Key(e => e.Uri);
mediaFile.Index(e => e.Uri);
mediaFile.Property(e => e.Title).MaxLength(256).Required();

var mediaFilePlaylistEntry = _modelBuilder.Entity<CPlaylistEntry<CMediaFile>>();
mediaFilePlaylistEntry.Key(e => e.MediaFile);
mediaFilePlaylistEntry.Reference(e => e.MediaFile).InverseReference();

作为一个简单的测试,我将忽略CPlaylistEntry <>并执行以下操作:

dbContext.Set<CMediaFile>().Add(new CMediaFile() { Uri = "irrelevant", Title = "" });
dbContext.SaveChanges()

这引发:

NotSupportedException:实体类型'CPlaylistEntry'上的'MediaFile'没有设置值,并且'CMediaFile'类型的属性没有可用的值生成器。在添加实体之前为属性设置值,或者为“ CMediaFile”类型的属性配置值生成器

我什至不了解此异常,也看不到为什么仅尝试存储CMediaFile实体时会出现CPlaylistEntry。我猜想这与我的模型定义有关-特别是将CPlaylistEntry的主键定义为不是简单类型,而是复杂类型-另一个实体。但是,我希望EF足够聪明,以至于可以将其归结为字符串Uri,因为该复杂类型已经声明了自己的主键,并且我已经将该属性声明为该类型的外键。

是否可以在EF中对这些类进行建模而无需从根本上重新设计它们以使其看起来更接近于相应的数据库表呢?过去我曾经使用过EF6数据库,所以这是我第一次尝试使用代码优先模式,并且我真的希望我可以将数据库看起来像是一团糟的问题隔离到我的模型定义中,并保持与.NET交互的“干净”类。

如果需要更多关于这些类型及其关系的解释,请问-我试图保持简短。

尼克·ACNB

怀疑当前是否支持(不确定是否最终会支持)。我试图通过稍作更改来重新创建模型,当尝试创建数据库时,我得到了:

System.NotSupportedException:无法映射属性“ PlaylistEntry`1MediaFile”,因为它当前不支持“ MediaFile”类型。

更新1

我认为您将MediaFile作为关键这一事实正在制造问题。我对您的模型进行了一些更改。我希望这不会破坏您的负面影响:

public interface IPlaylistEntry<T>
    where T : IMediaFile
{
    T MediaFile { get; set; }
}

public class PlaylistEntry<T> : IPlaylistEntry<T>
    where T : IMediaFile
{
    public int Id { get; set; }
    public string PlaylistInfo { get; set; } //added for testing purposes
    public T MediaFile { get; set; }
}

映射:

protected override void OnModelCreating(ModelBuilder builder)
  {
     builder.ForSqlServer().UseIdentity();

     builder.Entity<MediaFile>().ForRelational().Table("MediaFiles");
     builder.Entity<MediaFile>().Key(e => e.Uri);
     builder.Entity<MediaFile>().Index(e => e.Uri);
     builder.Entity<MediaFile>().Property(e => e.Title).MaxLength(256).Required();

     builder.Entity<PlaylistEntry<MediaFile>>().ForRelational().Table("MediaFileEntries");
     builder.Entity<PlaylistEntry<MediaFile>>().Key(e => e.Id);
     builder.Entity<PlaylistEntry<MediaFile>>().Reference(e => e.MediaFile).InverseReference();
 }

用法:

  var mediaFile = new MediaFile() {Uri = "irrelevant", Title = ""};
  context.Set<MediaFile>().Add(mediaFile);
  context.SaveChanges();

  context.Set<PlaylistEntry<MediaFile>>().Add(new PlaylistEntry<MediaFile>
  {
      MediaFile = mediaFile,
      PlaylistInfo = "test"
  });

  context.SaveChanges();

这可以正常工作并将正确的数据保存到数据库中。

您可以使用以下方法检索数据:

  var playlistEntryFromDb = context.Set<PlaylistEntry<MediaFile>>()
         .Include(plemf => plemf.MediaFile).ToList();

更新2

由于您不想以身份作为密钥,因此可以将Uri属性添加到播放列表类中,该类将用于PlaylistEntry和MediaFile之间的关系。

public class PlaylistEntry<T> : IPlaylistEntry<T>
    where T : IMediaFile
{
    public string Uri { get; set; }
    public string PlaylistInfo { get; set; }
    public T MediaFile { get; set; }
}

在这种情况下,映射如下所示:

    protected override void OnModelCreating(ModelBuilder builder)
    {
        builder.Entity<MediaFile>().ForRelational().Table("MediaFiles");
        builder.Entity<MediaFile>().Key(e => e.Uri);
        builder.Entity<MediaFile>().Index(e => e.Uri);
        builder.Entity<MediaFile>().Property(e => e.Title).MaxLength(256).Required();

        builder.Entity<PlaylistEntry<MediaFile>>().ForRelational().Table("MediaFileEntries");
        builder.Entity<PlaylistEntry<MediaFile>>().Key(e => e.Uri);
        builder.Entity<PlaylistEntry<MediaFile>>().Reference(e => e.MediaFile).InverseReference().ForeignKey<PlaylistEntry<MediaFile>>(e => e.Uri);
    }

插入数据的用法保持不变:

 var mediaFile = new MediaFile() { Uri = "irrelevant", Title = "" };
 context.Set<MediaFile>().Add(mediaFile);
 context.SaveChanges();

 context.Set<PlaylistEntry<MediaFile>>().Add(new PlaylistEntry<MediaFile>
 {
     MediaFile = mediaFile,
     PlaylistInfo = "test"
 });

 context.SaveChanges();

上面的这段代码会将“无关”放入PlaylistEntry Uri属性中,因为它用作外键。

并检索数据:

    var mediaFiles = context.Set<PlaylistEntry<MediaFile>>().Include(x => x.MediaFile).ToList();

联接将在两个表的Uri字段上发生。

本文收集自互联网,转载请注明来源。

如有侵权,请联系[email protected] 删除。

编辑于
0

我来说两句

0条评论
登录后参与评论

相关文章

来自分类Dev

在EF7中加载参考

来自分类Dev

在MVC6和EF7的BaseController中初始化DbContext吗?

来自分类Dev

是否可以在EF7中使用流畅的API添加CHECK约束?

来自分类Dev

EF7和SQLite麻烦大了,我可以将SQL Server CE与Mobile一起使用吗?

来自分类Dev

还有可能使用EF7将实体类型的配置放入外部类或函数中吗?

来自分类Dev

我可以创建从列中的整数值到它们在sql中表示的文本值的映射吗?

来自分类Dev

EF7加载列表中实体的子级

来自分类Dev

ChangeTracker.Entries()CurrentValue等于EF7中的OriginalValue

来自分类Dev

如何修复EF7中的此错误?

来自分类Dev

多对多EF7

来自分类Dev

EF7(代码优先)+ SQLite不会创建数据库和模型表

来自分类Dev

我可以在数据库中添加列,然后在模型中添加与这些列相对应的属性吗?

来自分类Dev

是否可以使用EF7执行自定义SQL查询

来自分类Dev

我可以将查询结果投影到EF生成的模型中吗?

来自分类Dev

EF7一对多映射

来自分类Dev

EF7 DBContext的配置错误?

来自分类Dev

使用EF7的存储库模式

来自分类Dev

EF7不保存对象图

来自分类Dev

EF7一对多映射

来自分类Dev

EF7错误插入默认日期

来自分类Dev

通用应用程序中具有EF7的数据库优先

来自分类Dev

在EF7中添加相同类型的多个导航属性

来自分类Dev

尝试在EF7和ASP.NET5中使用DbSet <TEntity> .Where()

来自分类Dev

如何在EF7(Core)中为同一表创建多个关系?

来自分类Dev

等效于Entity Framework Core 1(EF7)中的.HasOptional

来自分类Dev

在新配置下在EF7中切换ProxyCreation

来自分类Dev

EF7命令在VS2015 CTP 6中不起作用

来自分类Dev

代替EF7中的DbSet Create()方法使用什么,建议仅使用新的T()

来自分类Dev

在EF7中为谓词使用参数时,为什么不能使用ToListAsync()?

Related 相关文章

  1. 1

    在EF7中加载参考

  2. 2

    在MVC6和EF7的BaseController中初始化DbContext吗?

  3. 3

    是否可以在EF7中使用流畅的API添加CHECK约束?

  4. 4

    EF7和SQLite麻烦大了,我可以将SQL Server CE与Mobile一起使用吗?

  5. 5

    还有可能使用EF7将实体类型的配置放入外部类或函数中吗?

  6. 6

    我可以创建从列中的整数值到它们在sql中表示的文本值的映射吗?

  7. 7

    EF7加载列表中实体的子级

  8. 8

    ChangeTracker.Entries()CurrentValue等于EF7中的OriginalValue

  9. 9

    如何修复EF7中的此错误?

  10. 10

    多对多EF7

  11. 11

    EF7(代码优先)+ SQLite不会创建数据库和模型表

  12. 12

    我可以在数据库中添加列,然后在模型中添加与这些列相对应的属性吗?

  13. 13

    是否可以使用EF7执行自定义SQL查询

  14. 14

    我可以将查询结果投影到EF生成的模型中吗?

  15. 15

    EF7一对多映射

  16. 16

    EF7 DBContext的配置错误?

  17. 17

    使用EF7的存储库模式

  18. 18

    EF7不保存对象图

  19. 19

    EF7一对多映射

  20. 20

    EF7错误插入默认日期

  21. 21

    通用应用程序中具有EF7的数据库优先

  22. 22

    在EF7中添加相同类型的多个导航属性

  23. 23

    尝试在EF7和ASP.NET5中使用DbSet <TEntity> .Where()

  24. 24

    如何在EF7(Core)中为同一表创建多个关系?

  25. 25

    等效于Entity Framework Core 1(EF7)中的.HasOptional

  26. 26

    在新配置下在EF7中切换ProxyCreation

  27. 27

    EF7命令在VS2015 CTP 6中不起作用

  28. 28

    代替EF7中的DbSet Create()方法使用什么,建议仅使用新的T()

  29. 29

    在EF7中为谓词使用参数时,为什么不能使用ToListAsync()?

热门标签

归档