Linked List implementation Entity Framework Core

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP





.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty margin-bottom:0;







up vote
4
down vote

favorite
1












I am trying to create a data model where there are Document entities, which need to be in a defined order to each other. Think of an article that has sections which build up on one another.



Example:



Document1 -> Document3 -> Document2 -> Document6 -> Document5 -> Document4


I was trying to implement a linked list to achieve that. Unfortunately EF Core 2.0 does not support recursive queries. Therefore I needed a parent entity, named DocumentCollection. The requirement is to be able to get the Documents in the predefined order.



Please suggest improvements or alternative approaches.




Entity definitions



DocumentCollection model:



public class DocumentCollection

public int Id get; set;
public ICollection<Document> Documents get; set;

public DocumentCollection()

Documents = new HashSet<Document>();




Document model:



public class Document

public int Id get; set;
public string Name get; set;

#region Navigation Properties

public int CollectionId get; set;
public DocumentCollection Collection get; set;

public int? PredecessorId get; set;
public Document Predecessor get; set;

public int? SuccessorId get; set;
public Document Successor get; set;

#endregion



DbContext relationship mapping:



protected override void OnModelCreating(ModelBuilder modelBuilder)

modelBuilder.Entity<Product>().HasKey(product => product.Id);
modelBuilder.Entity<Product>().Property(product => product.Name).HasMaxLength(70);

modelBuilder.Entity<DocumentCollection>()
.HasKey(collection => collection.Id);

modelBuilder.Entity<Document>().HasKey(document => document.Id);
modelBuilder.Entity<Document>().Property(document => document.Name).HasMaxLength(70);

modelBuilder.Entity<DocumentCollection>()
.HasMany(collection => collection.Documents)
.WithOne(document => document.Collection)
.HasPrincipalKey(collection => collection.Id)
.HasForeignKey(document => document.CollectionId)
.OnDelete(DeleteBehavior.Cascade);

modelBuilder.Entity<Document>()
.HasOne(document => document.Predecessor)
.WithOne(document => document.Successor)
.HasPrincipalKey<Document>(principal => principal.Id)
.HasForeignKey<Document>(dependent => dependent.PredecessorId);

modelBuilder.Entity<Document>()
.HasOne(document => document.Successor)
.WithOne(document => document.Predecessor)
.HasPrincipalKey<Document>(principal => principal.Id)
.HasForeignKey<Document>(dependent => dependent.SuccessorId);

base.OnModelCreating(modelBuilder);




Service used to manage the entities:



public class DocumentService

private readonly DataContext _context;
public DbSet<Document> Entities => _context.Documents;

public DocumentService(DataContext context)

_context = context;


[...]



Creating an initial Document:



public async Task<Document> AddDocument(Document document)

document.Collection = new DocumentCollection();
var result = await Entities.AddAsync(document);
await _context.SaveChangesAsync();
return result.Entity;



Adding Document to a specific position:



public async Task<Document> AddDocumentSuccessor(int parentId, Document document)

var predecessor = await Entities
.Include(entity => entity.Successor)
.SingleOrDefaultAsync(entity => entity.Id == parentId);

if (predecessor == null)

return null;


document.CollectionId = predecessor.CollectionId;
var result = await Entities.AddAsync(document);
await _context.SaveChangesAsync();

var newEntity = result.Entity;

newEntity.PredecessorId = predecessor.Id;
if (predecessor.Successor != null)

newEntity.SuccessorId = predecessor.SuccessorId;


predecessor.SuccessorId = newEntity.Id;
if (predecessor.Successor != null)

predecessor.Successor.PredecessorId = newEntity.Id;


await _context.SaveChangesAsync();
return result.Entity;



Getting an ordered list of related Document entities:



public async Task<IEnumerable<Document>> GetRelatedDocuments(int id)

var collectionId = await Entities
.Where(entity => entity.Id == id)
.Select(entity => entity.CollectionId)
.SingleOrDefaultAsync();

if (collectionId == 0)

return null;


var result = await Entities
.Where(entity => entity.CollectionId == collectionId)
.Select(entity => new Document

Id = entity.Id,
Name = entity.Name,
CollectionId = entity.CollectionId,
PredecessorId = entity.PredecessorId,
SuccessorId = entity.SuccessorId
)
.ToArrayAsync();

return OrderByHierarchy(result);



Method used for sorting:



private static IEnumerable<Document> OrderByHierarchy(
IReadOnlyCollection<Document> documents)

if (documents.Count == 0)

yield break;


var dict = documents.ToDictionary
(
entity => entity.PredecessorId ?? 0,
entity => entity
);

var key = 0;
Document document;

do

document = dict[key];
yield return document;
key = document.Id;

while (document.SuccessorId != null);







share|improve this question





















  • This could have been so simple if instead of having parent/next-ids you'd have just created a property like Ordinal with the index of the document in the list.
    – t3chb0t
    Apr 12 at 19:22











  • @t3chb0t I thought about this as well. The thing that I found bad about this, is that when inserting new Document entities, I probably have to update allot of them at once.
    – Sebastian Krogull
    Apr 12 at 19:28
















up vote
4
down vote

favorite
1












I am trying to create a data model where there are Document entities, which need to be in a defined order to each other. Think of an article that has sections which build up on one another.



Example:



Document1 -> Document3 -> Document2 -> Document6 -> Document5 -> Document4


I was trying to implement a linked list to achieve that. Unfortunately EF Core 2.0 does not support recursive queries. Therefore I needed a parent entity, named DocumentCollection. The requirement is to be able to get the Documents in the predefined order.



Please suggest improvements or alternative approaches.




Entity definitions



DocumentCollection model:



public class DocumentCollection

public int Id get; set;
public ICollection<Document> Documents get; set;

public DocumentCollection()

Documents = new HashSet<Document>();




Document model:



public class Document

public int Id get; set;
public string Name get; set;

#region Navigation Properties

public int CollectionId get; set;
public DocumentCollection Collection get; set;

public int? PredecessorId get; set;
public Document Predecessor get; set;

public int? SuccessorId get; set;
public Document Successor get; set;

#endregion



DbContext relationship mapping:



protected override void OnModelCreating(ModelBuilder modelBuilder)

modelBuilder.Entity<Product>().HasKey(product => product.Id);
modelBuilder.Entity<Product>().Property(product => product.Name).HasMaxLength(70);

modelBuilder.Entity<DocumentCollection>()
.HasKey(collection => collection.Id);

modelBuilder.Entity<Document>().HasKey(document => document.Id);
modelBuilder.Entity<Document>().Property(document => document.Name).HasMaxLength(70);

modelBuilder.Entity<DocumentCollection>()
.HasMany(collection => collection.Documents)
.WithOne(document => document.Collection)
.HasPrincipalKey(collection => collection.Id)
.HasForeignKey(document => document.CollectionId)
.OnDelete(DeleteBehavior.Cascade);

modelBuilder.Entity<Document>()
.HasOne(document => document.Predecessor)
.WithOne(document => document.Successor)
.HasPrincipalKey<Document>(principal => principal.Id)
.HasForeignKey<Document>(dependent => dependent.PredecessorId);

modelBuilder.Entity<Document>()
.HasOne(document => document.Successor)
.WithOne(document => document.Predecessor)
.HasPrincipalKey<Document>(principal => principal.Id)
.HasForeignKey<Document>(dependent => dependent.SuccessorId);

base.OnModelCreating(modelBuilder);




Service used to manage the entities:



public class DocumentService

private readonly DataContext _context;
public DbSet<Document> Entities => _context.Documents;

public DocumentService(DataContext context)

_context = context;


[...]



Creating an initial Document:



public async Task<Document> AddDocument(Document document)

document.Collection = new DocumentCollection();
var result = await Entities.AddAsync(document);
await _context.SaveChangesAsync();
return result.Entity;



Adding Document to a specific position:



public async Task<Document> AddDocumentSuccessor(int parentId, Document document)

var predecessor = await Entities
.Include(entity => entity.Successor)
.SingleOrDefaultAsync(entity => entity.Id == parentId);

if (predecessor == null)

return null;


document.CollectionId = predecessor.CollectionId;
var result = await Entities.AddAsync(document);
await _context.SaveChangesAsync();

var newEntity = result.Entity;

newEntity.PredecessorId = predecessor.Id;
if (predecessor.Successor != null)

newEntity.SuccessorId = predecessor.SuccessorId;


predecessor.SuccessorId = newEntity.Id;
if (predecessor.Successor != null)

predecessor.Successor.PredecessorId = newEntity.Id;


await _context.SaveChangesAsync();
return result.Entity;



Getting an ordered list of related Document entities:



public async Task<IEnumerable<Document>> GetRelatedDocuments(int id)

var collectionId = await Entities
.Where(entity => entity.Id == id)
.Select(entity => entity.CollectionId)
.SingleOrDefaultAsync();

if (collectionId == 0)

return null;


var result = await Entities
.Where(entity => entity.CollectionId == collectionId)
.Select(entity => new Document

Id = entity.Id,
Name = entity.Name,
CollectionId = entity.CollectionId,
PredecessorId = entity.PredecessorId,
SuccessorId = entity.SuccessorId
)
.ToArrayAsync();

return OrderByHierarchy(result);



Method used for sorting:



private static IEnumerable<Document> OrderByHierarchy(
IReadOnlyCollection<Document> documents)

if (documents.Count == 0)

yield break;


var dict = documents.ToDictionary
(
entity => entity.PredecessorId ?? 0,
entity => entity
);

var key = 0;
Document document;

do

document = dict[key];
yield return document;
key = document.Id;

while (document.SuccessorId != null);







share|improve this question





















  • This could have been so simple if instead of having parent/next-ids you'd have just created a property like Ordinal with the index of the document in the list.
    – t3chb0t
    Apr 12 at 19:22











  • @t3chb0t I thought about this as well. The thing that I found bad about this, is that when inserting new Document entities, I probably have to update allot of them at once.
    – Sebastian Krogull
    Apr 12 at 19:28












up vote
4
down vote

favorite
1









up vote
4
down vote

favorite
1






1





I am trying to create a data model where there are Document entities, which need to be in a defined order to each other. Think of an article that has sections which build up on one another.



Example:



Document1 -> Document3 -> Document2 -> Document6 -> Document5 -> Document4


I was trying to implement a linked list to achieve that. Unfortunately EF Core 2.0 does not support recursive queries. Therefore I needed a parent entity, named DocumentCollection. The requirement is to be able to get the Documents in the predefined order.



Please suggest improvements or alternative approaches.




Entity definitions



DocumentCollection model:



public class DocumentCollection

public int Id get; set;
public ICollection<Document> Documents get; set;

public DocumentCollection()

Documents = new HashSet<Document>();




Document model:



public class Document

public int Id get; set;
public string Name get; set;

#region Navigation Properties

public int CollectionId get; set;
public DocumentCollection Collection get; set;

public int? PredecessorId get; set;
public Document Predecessor get; set;

public int? SuccessorId get; set;
public Document Successor get; set;

#endregion



DbContext relationship mapping:



protected override void OnModelCreating(ModelBuilder modelBuilder)

modelBuilder.Entity<Product>().HasKey(product => product.Id);
modelBuilder.Entity<Product>().Property(product => product.Name).HasMaxLength(70);

modelBuilder.Entity<DocumentCollection>()
.HasKey(collection => collection.Id);

modelBuilder.Entity<Document>().HasKey(document => document.Id);
modelBuilder.Entity<Document>().Property(document => document.Name).HasMaxLength(70);

modelBuilder.Entity<DocumentCollection>()
.HasMany(collection => collection.Documents)
.WithOne(document => document.Collection)
.HasPrincipalKey(collection => collection.Id)
.HasForeignKey(document => document.CollectionId)
.OnDelete(DeleteBehavior.Cascade);

modelBuilder.Entity<Document>()
.HasOne(document => document.Predecessor)
.WithOne(document => document.Successor)
.HasPrincipalKey<Document>(principal => principal.Id)
.HasForeignKey<Document>(dependent => dependent.PredecessorId);

modelBuilder.Entity<Document>()
.HasOne(document => document.Successor)
.WithOne(document => document.Predecessor)
.HasPrincipalKey<Document>(principal => principal.Id)
.HasForeignKey<Document>(dependent => dependent.SuccessorId);

base.OnModelCreating(modelBuilder);




Service used to manage the entities:



public class DocumentService

private readonly DataContext _context;
public DbSet<Document> Entities => _context.Documents;

public DocumentService(DataContext context)

_context = context;


[...]



Creating an initial Document:



public async Task<Document> AddDocument(Document document)

document.Collection = new DocumentCollection();
var result = await Entities.AddAsync(document);
await _context.SaveChangesAsync();
return result.Entity;



Adding Document to a specific position:



public async Task<Document> AddDocumentSuccessor(int parentId, Document document)

var predecessor = await Entities
.Include(entity => entity.Successor)
.SingleOrDefaultAsync(entity => entity.Id == parentId);

if (predecessor == null)

return null;


document.CollectionId = predecessor.CollectionId;
var result = await Entities.AddAsync(document);
await _context.SaveChangesAsync();

var newEntity = result.Entity;

newEntity.PredecessorId = predecessor.Id;
if (predecessor.Successor != null)

newEntity.SuccessorId = predecessor.SuccessorId;


predecessor.SuccessorId = newEntity.Id;
if (predecessor.Successor != null)

predecessor.Successor.PredecessorId = newEntity.Id;


await _context.SaveChangesAsync();
return result.Entity;



Getting an ordered list of related Document entities:



public async Task<IEnumerable<Document>> GetRelatedDocuments(int id)

var collectionId = await Entities
.Where(entity => entity.Id == id)
.Select(entity => entity.CollectionId)
.SingleOrDefaultAsync();

if (collectionId == 0)

return null;


var result = await Entities
.Where(entity => entity.CollectionId == collectionId)
.Select(entity => new Document

Id = entity.Id,
Name = entity.Name,
CollectionId = entity.CollectionId,
PredecessorId = entity.PredecessorId,
SuccessorId = entity.SuccessorId
)
.ToArrayAsync();

return OrderByHierarchy(result);



Method used for sorting:



private static IEnumerable<Document> OrderByHierarchy(
IReadOnlyCollection<Document> documents)

if (documents.Count == 0)

yield break;


var dict = documents.ToDictionary
(
entity => entity.PredecessorId ?? 0,
entity => entity
);

var key = 0;
Document document;

do

document = dict[key];
yield return document;
key = document.Id;

while (document.SuccessorId != null);







share|improve this question













I am trying to create a data model where there are Document entities, which need to be in a defined order to each other. Think of an article that has sections which build up on one another.



Example:



Document1 -> Document3 -> Document2 -> Document6 -> Document5 -> Document4


I was trying to implement a linked list to achieve that. Unfortunately EF Core 2.0 does not support recursive queries. Therefore I needed a parent entity, named DocumentCollection. The requirement is to be able to get the Documents in the predefined order.



Please suggest improvements or alternative approaches.




Entity definitions



DocumentCollection model:



public class DocumentCollection

public int Id get; set;
public ICollection<Document> Documents get; set;

public DocumentCollection()

Documents = new HashSet<Document>();




Document model:



public class Document

public int Id get; set;
public string Name get; set;

#region Navigation Properties

public int CollectionId get; set;
public DocumentCollection Collection get; set;

public int? PredecessorId get; set;
public Document Predecessor get; set;

public int? SuccessorId get; set;
public Document Successor get; set;

#endregion



DbContext relationship mapping:



protected override void OnModelCreating(ModelBuilder modelBuilder)

modelBuilder.Entity<Product>().HasKey(product => product.Id);
modelBuilder.Entity<Product>().Property(product => product.Name).HasMaxLength(70);

modelBuilder.Entity<DocumentCollection>()
.HasKey(collection => collection.Id);

modelBuilder.Entity<Document>().HasKey(document => document.Id);
modelBuilder.Entity<Document>().Property(document => document.Name).HasMaxLength(70);

modelBuilder.Entity<DocumentCollection>()
.HasMany(collection => collection.Documents)
.WithOne(document => document.Collection)
.HasPrincipalKey(collection => collection.Id)
.HasForeignKey(document => document.CollectionId)
.OnDelete(DeleteBehavior.Cascade);

modelBuilder.Entity<Document>()
.HasOne(document => document.Predecessor)
.WithOne(document => document.Successor)
.HasPrincipalKey<Document>(principal => principal.Id)
.HasForeignKey<Document>(dependent => dependent.PredecessorId);

modelBuilder.Entity<Document>()
.HasOne(document => document.Successor)
.WithOne(document => document.Predecessor)
.HasPrincipalKey<Document>(principal => principal.Id)
.HasForeignKey<Document>(dependent => dependent.SuccessorId);

base.OnModelCreating(modelBuilder);




Service used to manage the entities:



public class DocumentService

private readonly DataContext _context;
public DbSet<Document> Entities => _context.Documents;

public DocumentService(DataContext context)

_context = context;


[...]



Creating an initial Document:



public async Task<Document> AddDocument(Document document)

document.Collection = new DocumentCollection();
var result = await Entities.AddAsync(document);
await _context.SaveChangesAsync();
return result.Entity;



Adding Document to a specific position:



public async Task<Document> AddDocumentSuccessor(int parentId, Document document)

var predecessor = await Entities
.Include(entity => entity.Successor)
.SingleOrDefaultAsync(entity => entity.Id == parentId);

if (predecessor == null)

return null;


document.CollectionId = predecessor.CollectionId;
var result = await Entities.AddAsync(document);
await _context.SaveChangesAsync();

var newEntity = result.Entity;

newEntity.PredecessorId = predecessor.Id;
if (predecessor.Successor != null)

newEntity.SuccessorId = predecessor.SuccessorId;


predecessor.SuccessorId = newEntity.Id;
if (predecessor.Successor != null)

predecessor.Successor.PredecessorId = newEntity.Id;


await _context.SaveChangesAsync();
return result.Entity;



Getting an ordered list of related Document entities:



public async Task<IEnumerable<Document>> GetRelatedDocuments(int id)

var collectionId = await Entities
.Where(entity => entity.Id == id)
.Select(entity => entity.CollectionId)
.SingleOrDefaultAsync();

if (collectionId == 0)

return null;


var result = await Entities
.Where(entity => entity.CollectionId == collectionId)
.Select(entity => new Document

Id = entity.Id,
Name = entity.Name,
CollectionId = entity.CollectionId,
PredecessorId = entity.PredecessorId,
SuccessorId = entity.SuccessorId
)
.ToArrayAsync();

return OrderByHierarchy(result);



Method used for sorting:



private static IEnumerable<Document> OrderByHierarchy(
IReadOnlyCollection<Document> documents)

if (documents.Count == 0)

yield break;


var dict = documents.ToDictionary
(
entity => entity.PredecessorId ?? 0,
entity => entity
);

var key = 0;
Document document;

do

document = dict[key];
yield return document;
key = document.Id;

while (document.SuccessorId != null);









share|improve this question












share|improve this question




share|improve this question








edited Apr 12 at 18:30
























asked Apr 12 at 18:09









Sebastian Krogull

1213




1213











  • This could have been so simple if instead of having parent/next-ids you'd have just created a property like Ordinal with the index of the document in the list.
    – t3chb0t
    Apr 12 at 19:22











  • @t3chb0t I thought about this as well. The thing that I found bad about this, is that when inserting new Document entities, I probably have to update allot of them at once.
    – Sebastian Krogull
    Apr 12 at 19:28
















  • This could have been so simple if instead of having parent/next-ids you'd have just created a property like Ordinal with the index of the document in the list.
    – t3chb0t
    Apr 12 at 19:22











  • @t3chb0t I thought about this as well. The thing that I found bad about this, is that when inserting new Document entities, I probably have to update allot of them at once.
    – Sebastian Krogull
    Apr 12 at 19:28















This could have been so simple if instead of having parent/next-ids you'd have just created a property like Ordinal with the index of the document in the list.
– t3chb0t
Apr 12 at 19:22





This could have been so simple if instead of having parent/next-ids you'd have just created a property like Ordinal with the index of the document in the list.
– t3chb0t
Apr 12 at 19:22













@t3chb0t I thought about this as well. The thing that I found bad about this, is that when inserting new Document entities, I probably have to update allot of them at once.
– Sebastian Krogull
Apr 12 at 19:28




@t3chb0t I thought about this as well. The thing that I found bad about this, is that when inserting new Document entities, I probably have to update allot of them at once.
– Sebastian Krogull
Apr 12 at 19:28










1 Answer
1






active

oldest

votes

















up vote
1
down vote













I find you should stick to the same naming convention of the original LinkedListNode. This means that you should have a Preview and Next properties and not Predecessor and Successor respecitively.



I then would implement these two in another class, e.g. LinkedEntityNode:



public class LinkedEntityNode

public int Id get; set;
public int? NextId get; set;
public int? PreviousId get; set;



and put this in a separate table.



Then let the document reference the node:



public class Document

public int Id get; set;

public string Name get; set;

public int? NodeId get; set;

#region Navigation Properties

public LinkedEntityNode Node get; set;

#endregion



It would require a couple of adjustments to the models and to the sorting and finding logic but this way you could implement it once and for all and use it in any other project to link all kinds of stuff this way. Not just the Document entity.



I also think you don't need the collection type because as soon as you know one document (a node), you can rebuild it from there.






share|improve this answer

















  • 1




    In fact I'm going to solve it this way because I have a couple of uses for it already :-)
    – t3chb0t
    Apr 13 at 6:27










  • Would you think it might be a better idea to inherit from LinkedEntityNode because EF Core requires you to define one to one relationships with navigation properties on both related models?
    – Sebastian Krogull
    Apr 13 at 9:53










  • @SebastianKrogull I'm not sure but I'd rather not. I treat the LinkedEntityNode as an extension to the current model. It is possible that entities already are derived from another (domain) type. In this case it wouldn't be possible to link them anymore because multiple inheritance isn't possible in C#.
    – t3chb0t
    Apr 13 at 10:56











Your Answer




StackExchange.ifUsing("editor", function ()
return StackExchange.using("mathjaxEditing", function ()
StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix)
StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["\$", "\$"]]);
);
);
, "mathjax-editing");

StackExchange.ifUsing("editor", function ()
StackExchange.using("externalEditor", function ()
StackExchange.using("snippets", function ()
StackExchange.snippets.init();
);
);
, "code-snippets");

StackExchange.ready(function()
var channelOptions =
tags: "".split(" "),
id: "196"
;
initTagRenderer("".split(" "), "".split(" "), channelOptions);

StackExchange.using("externalEditor", function()
// Have to fire editor after snippets, if snippets enabled
if (StackExchange.settings.snippets.snippetsEnabled)
StackExchange.using("snippets", function()
createEditor();
);

else
createEditor();

);

function createEditor()
StackExchange.prepareEditor(
heartbeatType: 'answer',
convertImagesToLinks: false,
noModals: false,
showLowRepImageUploadWarning: true,
reputationToPostImages: null,
bindNavPrevention: true,
postfix: "",
onDemand: true,
discardSelector: ".discard-answer"
,immediatelyShowMarkdownHelp:true
);



);








 

draft saved


draft discarded


















StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f191903%2flinked-list-implementation-entity-framework-core%23new-answer', 'question_page');

);

Post as a guest






























1 Answer
1






active

oldest

votes








1 Answer
1






active

oldest

votes









active

oldest

votes






active

oldest

votes








up vote
1
down vote













I find you should stick to the same naming convention of the original LinkedListNode. This means that you should have a Preview and Next properties and not Predecessor and Successor respecitively.



I then would implement these two in another class, e.g. LinkedEntityNode:



public class LinkedEntityNode

public int Id get; set;
public int? NextId get; set;
public int? PreviousId get; set;



and put this in a separate table.



Then let the document reference the node:



public class Document

public int Id get; set;

public string Name get; set;

public int? NodeId get; set;

#region Navigation Properties

public LinkedEntityNode Node get; set;

#endregion



It would require a couple of adjustments to the models and to the sorting and finding logic but this way you could implement it once and for all and use it in any other project to link all kinds of stuff this way. Not just the Document entity.



I also think you don't need the collection type because as soon as you know one document (a node), you can rebuild it from there.






share|improve this answer

















  • 1




    In fact I'm going to solve it this way because I have a couple of uses for it already :-)
    – t3chb0t
    Apr 13 at 6:27










  • Would you think it might be a better idea to inherit from LinkedEntityNode because EF Core requires you to define one to one relationships with navigation properties on both related models?
    – Sebastian Krogull
    Apr 13 at 9:53










  • @SebastianKrogull I'm not sure but I'd rather not. I treat the LinkedEntityNode as an extension to the current model. It is possible that entities already are derived from another (domain) type. In this case it wouldn't be possible to link them anymore because multiple inheritance isn't possible in C#.
    – t3chb0t
    Apr 13 at 10:56















up vote
1
down vote













I find you should stick to the same naming convention of the original LinkedListNode. This means that you should have a Preview and Next properties and not Predecessor and Successor respecitively.



I then would implement these two in another class, e.g. LinkedEntityNode:



public class LinkedEntityNode

public int Id get; set;
public int? NextId get; set;
public int? PreviousId get; set;



and put this in a separate table.



Then let the document reference the node:



public class Document

public int Id get; set;

public string Name get; set;

public int? NodeId get; set;

#region Navigation Properties

public LinkedEntityNode Node get; set;

#endregion



It would require a couple of adjustments to the models and to the sorting and finding logic but this way you could implement it once and for all and use it in any other project to link all kinds of stuff this way. Not just the Document entity.



I also think you don't need the collection type because as soon as you know one document (a node), you can rebuild it from there.






share|improve this answer

















  • 1




    In fact I'm going to solve it this way because I have a couple of uses for it already :-)
    – t3chb0t
    Apr 13 at 6:27










  • Would you think it might be a better idea to inherit from LinkedEntityNode because EF Core requires you to define one to one relationships with navigation properties on both related models?
    – Sebastian Krogull
    Apr 13 at 9:53










  • @SebastianKrogull I'm not sure but I'd rather not. I treat the LinkedEntityNode as an extension to the current model. It is possible that entities already are derived from another (domain) type. In this case it wouldn't be possible to link them anymore because multiple inheritance isn't possible in C#.
    – t3chb0t
    Apr 13 at 10:56













up vote
1
down vote










up vote
1
down vote









I find you should stick to the same naming convention of the original LinkedListNode. This means that you should have a Preview and Next properties and not Predecessor and Successor respecitively.



I then would implement these two in another class, e.g. LinkedEntityNode:



public class LinkedEntityNode

public int Id get; set;
public int? NextId get; set;
public int? PreviousId get; set;



and put this in a separate table.



Then let the document reference the node:



public class Document

public int Id get; set;

public string Name get; set;

public int? NodeId get; set;

#region Navigation Properties

public LinkedEntityNode Node get; set;

#endregion



It would require a couple of adjustments to the models and to the sorting and finding logic but this way you could implement it once and for all and use it in any other project to link all kinds of stuff this way. Not just the Document entity.



I also think you don't need the collection type because as soon as you know one document (a node), you can rebuild it from there.






share|improve this answer













I find you should stick to the same naming convention of the original LinkedListNode. This means that you should have a Preview and Next properties and not Predecessor and Successor respecitively.



I then would implement these two in another class, e.g. LinkedEntityNode:



public class LinkedEntityNode

public int Id get; set;
public int? NextId get; set;
public int? PreviousId get; set;



and put this in a separate table.



Then let the document reference the node:



public class Document

public int Id get; set;

public string Name get; set;

public int? NodeId get; set;

#region Navigation Properties

public LinkedEntityNode Node get; set;

#endregion



It would require a couple of adjustments to the models and to the sorting and finding logic but this way you could implement it once and for all and use it in any other project to link all kinds of stuff this way. Not just the Document entity.



I also think you don't need the collection type because as soon as you know one document (a node), you can rebuild it from there.







share|improve this answer













share|improve this answer



share|improve this answer











answered Apr 13 at 6:21









t3chb0t

32k54195




32k54195







  • 1




    In fact I'm going to solve it this way because I have a couple of uses for it already :-)
    – t3chb0t
    Apr 13 at 6:27










  • Would you think it might be a better idea to inherit from LinkedEntityNode because EF Core requires you to define one to one relationships with navigation properties on both related models?
    – Sebastian Krogull
    Apr 13 at 9:53










  • @SebastianKrogull I'm not sure but I'd rather not. I treat the LinkedEntityNode as an extension to the current model. It is possible that entities already are derived from another (domain) type. In this case it wouldn't be possible to link them anymore because multiple inheritance isn't possible in C#.
    – t3chb0t
    Apr 13 at 10:56













  • 1




    In fact I'm going to solve it this way because I have a couple of uses for it already :-)
    – t3chb0t
    Apr 13 at 6:27










  • Would you think it might be a better idea to inherit from LinkedEntityNode because EF Core requires you to define one to one relationships with navigation properties on both related models?
    – Sebastian Krogull
    Apr 13 at 9:53










  • @SebastianKrogull I'm not sure but I'd rather not. I treat the LinkedEntityNode as an extension to the current model. It is possible that entities already are derived from another (domain) type. In this case it wouldn't be possible to link them anymore because multiple inheritance isn't possible in C#.
    – t3chb0t
    Apr 13 at 10:56








1




1




In fact I'm going to solve it this way because I have a couple of uses for it already :-)
– t3chb0t
Apr 13 at 6:27




In fact I'm going to solve it this way because I have a couple of uses for it already :-)
– t3chb0t
Apr 13 at 6:27












Would you think it might be a better idea to inherit from LinkedEntityNode because EF Core requires you to define one to one relationships with navigation properties on both related models?
– Sebastian Krogull
Apr 13 at 9:53




Would you think it might be a better idea to inherit from LinkedEntityNode because EF Core requires you to define one to one relationships with navigation properties on both related models?
– Sebastian Krogull
Apr 13 at 9:53












@SebastianKrogull I'm not sure but I'd rather not. I treat the LinkedEntityNode as an extension to the current model. It is possible that entities already are derived from another (domain) type. In this case it wouldn't be possible to link them anymore because multiple inheritance isn't possible in C#.
– t3chb0t
Apr 13 at 10:56





@SebastianKrogull I'm not sure but I'd rather not. I treat the LinkedEntityNode as an extension to the current model. It is possible that entities already are derived from another (domain) type. In this case it wouldn't be possible to link them anymore because multiple inheritance isn't possible in C#.
– t3chb0t
Apr 13 at 10:56













 

draft saved


draft discarded


























 


draft saved


draft discarded














StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f191903%2flinked-list-implementation-entity-framework-core%23new-answer', 'question_page');

);

Post as a guest













































































Popular posts from this blog

Greedy Best First Search implementation in Rust

Function to Return a JSON Like Objects Using VBA Collections and Arrays

C++11 CLH Lock Implementation