【问题标题】:Entity Framework - Generic method for processing identical objects实体框架 - 处理相同对象的通用方法
【发布时间】:2016-03-09 11:24:41
【问题描述】:

我有几个相同的对象组,每个对象组都由映射到主表和耦合链接表的实体组成,例如

//group1
class OrderNote
{
    public int OrderNoteId {get; set;}
    public virtual ICollecton<OrderNoteTag> OrderNoteTags {get; set;}
}
class OrderNoteTag
{
    public int OrderNoteId {get; set;}
    public int TagId {get; set;}
}
//////
//group 2
class ClientNote
{
    public int ClientNoteId {get; set;}
    public virtual ICollecton<ClientNoteTag> ClientNoteTags {get; set;}
}
class ClientNoteTag
{
    public int ClientNoteId {get; set;}
    public int TagId {get; set;}
}
/////

现在,我需要一种方法,它允许我通过相同的例程处理主要对象,因此我不必多次重复相同的代码。我的想法是为便笺和标签创建一些基类,具体类型将从它们继承,并且该方法将接受便笺的基类。但是我不知道如何声明和继承导航属性,所以它们映射到具体的标签类型上,但可以作为基类型处理。

应该是这样的:

public class TagBase
{
    public int NoteId {get; set;}
    public int TagId {get; set;}
} 

public class NoteBase
{
    public int NoteId {get; set;}
    public virtual ICollecton<TagBase> NoteTags {get; set;}
}

//then we inherit
public class OrderNoteTag : TagBase {}

public class OrderNote : NoteBase
{
    //Here we should pass the concrete type OrderNoteTag to NoteTags collection somehow
}

// Then we have method, where we should be able to pass OrderNote or ClientNote
public void ProcessNote(NoteBase note)
{
    foreach(var tag in note.NoteTags){...blah-blah-blah...}
}

提前致谢。

【问题讨论】:

  • 您是否尝试将 ProcessNote 的签名更改为 public void ProcessNote&lt;TNote&gt;(TNote note) where TNote : NoteBase
  • @raderick,我需要通用算法来保存笔记,而不是取决于它们的类型。他们应该以基类的形式来到服务器。同样,主要问题是继承具有正确类型的导航属性,但这并不能解决问题。
  • 我不太确定你想在这里做什么,也许你也应该看看访客模式。
  • 当您尝试您建议的代码时会发生什么?你有错误吗?它不会编译吗?

标签: c# entity-framework oop


【解决方案1】:

考虑这种方法,它是基于接口的。现在你可以使用INote&lt;INoteTag&gt; 类型而不是NoteBase,看看我的答案的结尾,但是你应该使用foreach 循环中的NoteTags 属性而不是NoteTagsCustom() 方法,我希望这对你来说并不重要.

型号:

public interface INote<out T> where T : INoteTag
{
    int NoteId { get; set; }        
    IEnumerable<T> NoteTagsCustom();
}

public interface INoteTag
{
    int NoteTagId { get; set; }
    int TagId { get; set; }
}

public class OrderNote : INote<OrderNoteTag>
{
    [Key]
    public int NoteId { get; set; }
    public virtual ICollection<OrderNoteTag> NoteTags { get; set; }

    public IEnumerable<OrderNoteTag> NoteTagsCustom()
    {
        return NoteTags;
    }
}
public class OrderNoteTag : INoteTag
{
    [Key]
    public int NoteTagId { get; set; }
    [ForeignKey("OrderNote")]
    public int TagId { get; set; }
    public virtual OrderNote OrderNote { get; set; }
}

public class ClientNote : INote<ClientNoteTag>
{
    [Key]
    public int NoteId { get; set; }
    public virtual ICollection<ClientNoteTag> NoteTags { get; set; }

    public IEnumerable<ClientNoteTag> NoteTagsCustom()
    {
        return NoteTags;
    }
}
public class ClientNoteTag : INoteTag
{
    [Key]
    public int NoteTagId { get; set; }
    [ForeignKey("ClientNote")]
    public int TagId { get; set; }
    public virtual ClientNote ClientNote { get; set; }
}

实施:

//important: INote<INoteTag> instead of NoteBase!
public void ProcessNote(INote<INoteTag> note)
{
    //important: NoteTagsCustom() instead of NoteTags!
    foreach(var tag in note.NoteTagsCustom()){...blah-blah-blah...}
}

【讨论】:

  • 谢谢,这正是我想要的。我使用通用基类让它工作,但这种方法似乎更好。
  • 一点也不。您使用类继承的方法是一个很好且最明显的模式,但在 EF 的情况下,它不是很合适,因为我们必须遵循 EF 与创建表、它们之间的关系和其他特性以及所有这些相关的特定规则和约定用一系列适用的模式限制我们。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-06-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多