這些模型可以在EF7中表示嗎?

c# entity-framework-core

我試圖在我自己的項目中使用來自另一個程序集的一些類作為我可以使用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。

所以我開始像這樣建模:

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

作為一個簡單的測試,我忽略了CPlaylistEntry <>並且只做:

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

拋出:

NotSupportedException:實體類型“CPlaylistEntry”上的“MediaFile”沒有設置值,並且沒有值生成器可用於“CMediaFile”類型的屬性。在添加實體之前為屬性設置值,或者為“CMediaFile”類型的屬性配置值生成器

我甚至不理解這個例外,當我只想存儲一個CMediaFile實體時,我不明白為什麼CPlaylistEntry會出現。我猜這與我的模型定義有關 - 特別是將CPlaylistEntry的主鍵定義為不是簡單類型,而是複雜類型 - 另一個實體。但是我希望EF足夠聰明,可以理解它歸結為一個字符串Uri,因為該複雜類型已經聲明了自己的主鍵,並且我已將該屬性聲明為該類型的外鍵。

是否有可能在EF中對這些類進行建模而不是從根本上重新設計它們以更接近相應的數據庫表?我以前一直使用EF6數據庫,所以這是我第一次嘗試使用代碼優先模式,我真的希望能夠將數據庫可能看起來像是我的模型定義,並保持我在.NET中與之交互的“乾淨”類。

如果需要對這些類型及其關係進行更多解釋,請問 - 我試圖保持這種簡短。

一般承認的答案

懷疑這是目前支持的(不確定它最終是否會)我試圖通過輕微的更改重新創建您的模型,當我嘗試創建數據庫時,我得到:

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

映射:

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

用法:

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

這樣可以將正確的數據保存到數據庫中。

您可以使用以下方法檢索數據:

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

更新2

由於您不希望將標識作為鍵,因此可以將Uri屬性添加到playlistentry類,該類將用於PlaylistEntry和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; }
}

以下是這種情況下的映射:

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

插入數據的用法保持不變:

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

上面的代碼會將“無關”放在PlaylistEntry Uri屬性中,因為它被用作外鍵。

並檢索數據:

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

連接將在兩個表中的Uri字段上進行。




許可下: CC-BY-SA with attribution
不隸屬於 Stack Overflow
這個KB合法嗎? 是的,了解原因
許可下: CC-BY-SA with attribution
不隸屬於 Stack Overflow
這個KB合法嗎? 是的,了解原因