简体   繁体   中英

Entity Framework - Generic method for processing identical objects

I have several identical object groups, each of them consists of entities mapped to main table and couple linking tables, for example

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

Now, I need a method which allows me to process the main objects by the same routine, so I won't have to duplicate the same code a lot of times. My idea is to have some base classes for notes and tags, the concrete types will inherit from them, and the method will accept the base type for note. But I can't figure out how to declare and inherit the navigation properties , so they are mapped on the concrete tag type, but can be processed as base type.

Here's something like it should be:

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

Thanks in advance.

Consider this approach, it is based on interfaces. Now you can use type INote<INoteTag> instead of NoteBase , look at the end of my answer, but instead of NoteTags property inside foreach loop you should use NoteTagsCustom() method, I hope that is not critical for you.

MODELS:

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

IMPLEMENTATION:

//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...}
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM