I'm beginner at EF and code contract, for doing a project I use the EF6 and code contract.
As you know in DB first approach, EF automatically generates classes corresponding to the DB entities, I added contracts to the partial classes which I defined manually.
EF generated class:
public partial class Article
{
public Article()
{
this.Comment = new HashSet<Comment>();
}
public int articleId { get; set; }
public string title { get; set; }
public string contentText { get; set; }
public System.DateTime creationDate { get; set; }
public System.DateTime modificationDate { get; set; }
public int numOfVisits { get; set; }
public bool enabled { get; set; }
public int creatorId { get; set; }
public int categoryId { get; set; }
public string img { get; set; }
public virtual ICollection<Comment> Comment { get; set; }
public virtual Category Category { get; set; }
public virtual Administrator Administrator { get; set; }
}
and manually defined class:
public partial class Article
{
[ContractInvariantMethod]
private void ObjectInvariant()
{
Contract.Invariant(contentText != null);
}
public Article(string title, string img, int catid, string content)
{
Contract.Ensures(this.title.Equals(title));
Contract.Ensures(this.img.Equals(img));
Contract.Ensures(categoryId.Equals(catid));
Contract.Ensures(Enumerable.SequenceEqual(Contract.OldValue(content), content));
this.title = title;
this.img = img;
categoryId = catid;
contentText = content;
creationDate = DateTime.Now;
modificationDate = DateTime.Now;
numOfVisits = 0;
enabled = true;
DBConnection.addObject<Article>(this);
}
public Article editArticle(int id,string title, string img, int catid, string content)
{
using (var c = new SabaDataEntity())
{
var art = c.Article.FirstOrDefault(i => i.articleId == id);
if(art != null)
{
art.title = title;
art.img = img;
art.categoryId = catid;
art.contentText = content;
}
c.SaveChanges();
return art;
}
}
public Article deleteById(int id)
{
using (var c = new SabaDataEntity())
{
var obj = c.Article.FirstOrDefault(i => i.articleId == id);
if (obj != null)
{
c.Article.Remove(obj);
c.SaveChanges();
return obj;
}
return obj;
}
}
public List<Article> getAll()
{
using (var c = new SabaDataEntity())
{
return c.Article.ToList();
}
}
public string getCategoryName()
{
using (var c = new SabaDataEntity())
{
var cat = c.Category.FirstOrDefault(i => i.categoryId == this.categoryId);
if (cat != null)
return cat.persianTitle;
return "";
}
}
public Article get(int id)
{
using (var c = new SabaDataEntity())
{
return c.Article.FirstOrDefault(i => i.articleId == id);
}
}
}
The problem which occurred when I calling a method of this class in the project is a violation of invariant, in fact this error :
Invariant failed: contentText != null
Now, is it for availability of two constructors?
And how can I solve this problem?
You can create another class for data access (with EF) as repository and avoid this sort of contract errors; e.g:
public class GenericRepository<T>: IDisposable where T : class
{
private SabaDataEntity db = null;
private DbSet<T> table = null;
static readonly GenericRepository<T> instance = new GenericRepository<T>();
public static readonly GenericRepository<T> Instance
{
get
{
return instance;
}
}
public GenericRepository()
{
this.db = new SabaDataEntity();
table = db.Set<T>();
}
public List<T> getAll()
{
return table.ToList();
}
public T getById(int id)
{
return table.Find(id);
}
}
from here