I'm working on updating a GitHub project that I use at work, but I think the person abandoned the project as there is a pull request for it since 2014. At work we use a Repository pattern with NHibernate and mappings and so forth but this project they use Entity 4.? I had to update the project to use .Net 4.6.1, and because of that I had to update to Entity 5.0. (I know I could have done 6.0 or greater, but I don't want to break the existing code and 6.0 gave me compiler errors which I don't know how to fix yet). The existing DataContext has a DBSet for all 3 tables (which I don't like) so I'm slowly splitting that into individual repositories. Here is what I have thus far. First the POCO, and interface for said repository
public class LogSubscription
{
public int LogSubscriptionId { get; set; }
public string Name { get; set; }
public string Url { get; set; }
public string PluginTypeName { get; set; }
}
public interface ISubscriptionRepository: IDisposable
{
LogSubscription GetSubscription(string name);
void SaveSubscription(LogSubscription logSubscription);
void DeleteSubscription(LogSubscription logSubscription);
}
I made it like that so I can easily mock out the repository without having to drag Entity with me. Now the implementation. Sorry if it makes your eyes bleed from any blaring code smells.
LogSubscriptionDataContext
internal class LogSubscriptionDataContext : DbContext
{
public LogSubscriptionDataContext()
:base("SourceLog")
{
Database.SetInitializer(new DropCreateDatabaseIfModelChanges<LogSubscriptionDataContext>());
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
modelBuilder.Entity<Models.LogSubscriptionDto>().ToTable("LogSubscription");
}
}
SubscriptionRepository
public class SubscriptionRepository : ISubscriptionRepository
{
private readonly DbContext _context;
private readonly IDbSet<LogSubscriptionDto> _logSubscriptions;
public SubscriptionRepository()
{
_context = new LogSubscriptionDataContext();
_logSubscriptions = _context.Set<LogSubscriptionDto>();
}
public LogSubscription GetSubscription(string name)
{
return (LogSubscription)_logSubscriptions.Find(name);
}
public void SaveSubscription(LogSubscription logSubscription)
{
if (_logSubscriptions.Find(logSubscription.Name) != null)
return;
_logSubscriptions.Add((LogSubscriptionDto)logSubscription);
_context.SaveChanges();
}
public void DeleteSubscription(LogSubscription logSubscription)
{
_logSubscriptions.Remove(_logSubscriptions.Find(logSubscription.Name));
_context.SaveChanges();
}
private bool disposedValue = false;
protected virtual void Dispose(bool disposing)
{
if (!disposedValue)
{
if (disposing)
{
_context.SaveChanges();
_context.Dispose();
}
disposedValue = true;
}
}
public void Dispose()
{
Dispose(true);
}
}
LogSubscriptionDto
[Table("LogSubscription")]
internal class LogSubscriptionDto
{
[DatabaseGenerated(DatabaseGeneratedOption.Identity)]
public int LogSubscriptionId { get; set; }
[Key]
public string Name { get; set; }
[Required]
public string Url { get; set; }
[Required]
public string PluginTypeName { get; set; }
public LogSubscriptionDto()
{
}
public LogSubscriptionDto(string name)
{
Name = name;
}
public LogSubscriptionDto(Core.Models.LogSubscription subscription)
{
LogSubscriptionId = subscription.LogSubscriptionId;
Name = subscription.Name;
PluginTypeName = subscription.PluginTypeName;
Url = subscription.Url;
}
public static explicit operator LogSubscriptionDto(Core.Models.LogSubscription subscription)
{
return new LogSubscriptionDto(subscription);
}
public static explicit operator Core.Models.LogSubscription(LogSubscriptionDto subscription)
{
return (subscription == null) ?
null :
new Core.Models.LogSubscription
{
LogSubscriptionId = subscription.LogSubscriptionId,
Name = subscription.Name,
PluginTypeName = subscription.PluginTypeName,
Url = subscription.Url,
};
}
}
Integration Test
[TestFixture]
public class SubscriptionRepositoryTests
{
[Test]
public void CanSaveSubscription()
{
var logSubscription = new LogSubscription
{
Name = "Robert",
PluginTypeName = "Git",
Url = "http://codereview.stackexchange.com/"
};
LogSubscription subscription = null;
subscription = CRD_Object(logSubscription);
Assert.That(subscription.Name, Is.EqualTo(logSubscription.Name));
Assert.That(subscription.PluginTypeName, Is.EqualTo(logSubscription.PluginTypeName));
Assert.That(subscription.Url, Is.EqualTo(logSubscription.Url));
Assert.That(subscription, Is.Not.EqualTo(logSubscription));
}
private static LogSubscription CRD_Object(LogSubscription logSubscription)
{
LogSubscription subscription;
using (Core.Repositories.ISubscriptionRepository repo = new SubscriptionRepository())
{
repo.SaveSubscription(logSubscription);
subscription = repo.GetSubscription("Robert");
repo.DeleteSubscription(logSubscription);
Assert.That(repo.GetSubscription("Robert"), Is.Null);
}
return subscription;
}
}
There are three things I'm up in the air about. One is getting the Subscription by its primary key. I feel like I should pass in the POCO, then find by the primary key (I tried passing in the Dto in the find method but it said it needed a scaler object). The other is setting the initializer in the DataContext. I just don't know where to put it, and I need it because Entity was throwing an exception saying it couldn't change the table or something because I changed my Dto. Lastly I'm thinking I'm going to remove the Id because in the UI its not used, and in the Find method it isn't used. The UI relies on the name of the subscription so in my opinion 3 strikes and you are out. Thoughts?