Reputation: 2266
I have two different entities (database first) that have the exact same structure but different naming conventions. Is there a way I can simplify the seemingly duplicated code that comes from querying them (ie in DoWorkWithSimilar
)?
I have tried doing something with generics but am having troubles getting the linq queries to work. Also I try to shy away from generics when possible because I like to be more explicit. Nevertheless, the DoWorkWithSimilar
methods in the two respective classes are extremely similar. I am trying to think of a better way to streamline these two classes (DoWorkSimilarOne
and DoWorkSimilarTwo
) however, due to my constraint on the structure of the underlying classes... I am struggling. Is there no better way?
public class DoWorkSimilarOne : IDoWork
{
public IUnitOfWork unitOfWork;
public DoWorkSimilarOne(IUnitOfWork _unitOfWork)
{
unitOfWork = _unitOfWork;
}
public IEnumerable<int> DoWorkWithSimilar(IEnumerable<int> otherIds)
{
IEnumerable<int> similarOneIds = unitOfWork.OtherSimilarOnes
.Where(x => otherIds.Contains(x.Other.OtherId))
.SelectMany(x => x.SimilarOnes)
.Select(x => x.SimilarOneId).ToList();
return similarOneIds;
}
}
public class DoWorkSimilarTwo : IDoWork
{
public IUnitOfWork unitOfWork;
public DoWorkSimilarTwo(IUnitOfWork _unitOfWork)
{
unitOfWork = _unitOfWork;
}
public IEnumerable<int> DoWorkWithSimilar(IEnumerable<int> otherIds)
{
IEnumerable<int> similarTwoIds = unitOfWork.OtherSimilarTwos
.Where(x => otherIds.Contains(x.Other.OtherId))
.SelectMany(x => x.SimilarTwos)
.Select(x => x.SimilarTwoId).ToList();
return similarTwoIds;
}
}
public class SimilarOne
{
public int SimilarOneId { get; set; }
public OtherSimilarOnes OtherSimilarOne { get; set; }
}
public class SimilarTwo
{
public int SimilarTwoId { get; set; }
public OtherSimilarTwos OtherSimilarTwo { get; set; }
}
public class Other
{
public int OtherId { get; set; }
}
public class OtherSimilarOnes
{
public int Id { get; set; }
public Other Other { get; set; }
public IEnumerable<SimilarOne> SimilarOnes { get; set; }
}
public class OtherSimilarTwos
{
public int Id { get; set; }
public Other Other { get; set; }
public IEnumerable<SimilarTwo> SimilarTwos { get; set; }
}
public interface IDoWork
{
IEnumerable<int> DoWorkWithSimilar(IEnumerable<int> otherIds);
}
Upvotes: 0
Views: 108
Reputation: 7970
Seems to me that you just need to make your method generic and add some base classes, right?
public abstract class ObjectWithId
{
public int Id { get; set; }
}
public class ObjectThatRelates<T> : ObjectWithId
where T : ObjectWithId
{
public int OtherId { get; set; }
public IEnumerable<T> Similar { get; set; }
}
public class Object1 : ObjectWithId
{
public ObjectThatRelates<Object1> { get; set; }
}
public class Object2 : ObjectWithId
{
public ObjectThatRelates<Object2> { get; set; }
}
Then your methods become:
public IEnumerable<int> DoWorkWithSimilar<T>(IEnumerable<int> otherIds)
{
IEnumerable<int> similarOneIds = unitOfWork.ObjectThatRelates<T>
.Where(x => otherIds.Contains(x.OtherId))
.SelectMany(x => x.Similar)
.Select(x => x.Id).ToList();
return similarOneIds;
}
Of course, your definition of IUnitOfWork
will have to change so that it can return either ObjectThatRelates<Object1>
or ObjectThatRelates<Object2>
but this should allow you to avoid duplication of effort.
Upvotes: 1