1

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?

Majid
  • 13,853
  • 15
  • 77
  • 113
Meysam PH
  • 248
  • 3
  • 6
  • 1
    Off topic, but very important: don't use this kind of active-record like constructs. `Article` should be a persistent-ignorant class. – Gert Arnold Dec 25 '14 at 21:40
  • for achieve the persistant-ignorant classes I must don't use the EF! or? – Meysam PH Dec 25 '14 at 21:49
  • 1
    He means making `Article` just a simple "holder" for values, and writting the logic for retrieving/storing in a different class (usually a DAO). – SJuan76 Dec 25 '14 at 21:59
  • 1
    Surely you can use EF. But EF has the repository/unit of work paradigm, which is totally different than active record. I'd suggest you look at some example applications using EF to get the gist of it. This is too broad a subject for an answer. But let me reveal one thing: EF provides repositories (`DbSet`) and UoW (`DbContext`) out of the box. Often people starting to work with EF blindly follow these generic repository evangelists. Keep it simple: simple service methods working on simple POCOs using contexts and `DbSet`s. – Gert Arnold Dec 25 '14 at 21:59
  • @SJuan76 No. Not DAO either. Active record/DAO all encourage single database interactions for single entities. They make it much much harder to deal with object graphs when compared to EF. – Gert Arnold Dec 25 '14 at 22:04

1 Answers1

1

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

Majid
  • 13,853
  • 15
  • 77
  • 113