Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

c# Type Inference - Error - There is no implicit reference conversion from

I have a method that loops through a list of guids and saves them to a database via DbContext. B is a DbSet collection of WebObjects (example: DbSet<MlaPerson> MlaPersons)

protected void AddRelatedWebObject<A, B>(A mlaObject, B inputObject, List<Guid> guids) 
    where A : WebObject 
    where B : DbSet<WebObject>
{
    foreach (Guid guid in guids)
    {
        mlaObject.RelatedWebObjects.Add(inputObject.Find(guid));
        _db.SaveChanges();
    }
}

usage:

foreach (ArticleRelationships item in articleRelationships)
{
    MlaArticle article = new MlaArticle();
    article = _db.MlaArticles.Include(m => m.WebSite).Where(m => m.Id == item.ArticleId).First();
    AddRelatedWebObject<MlaArticle, DbSet<MlaPerson>>(article, _db.MlaPersons, item.PersonIds);
}

_db.MlaPersons are defined as:

public class ECM2Context : DbContext
{
    public DbSet<MlaPerson> MlaPersons { get; set; }
}

and MlaPerson is defined as:

public class MlaPerson : WebObject, IValidatableObject
{
    ...
}

I thought that by inferring that B was DbSet<WebObject> would work because MlaPerson's base class is WebObject, but I'm wrong. I'm getting the error:

The type 'System.Data.Entity.DbSet<ExternalContentManager.Models.MlaPerson>' cannot be used as a type parameter 'B' in the generic type or method 'AddRelatedWebObjects'. There is not implicit reference conversion from 'System.Data.Entity.DbSet<ExternalContentManager.Models.MlaPerson>' to 'System.Data.Entity.DbSet<ExternalContentManager.Models.WebObject>'

I would really appreciate any and all help offered. Thanks for your help. B

like image 201
bflemi3 Avatar asked Dec 05 '22 20:12

bflemi3


1 Answers

You are making a common generics error- assuming that collections are covariant. That is, a an instance of List<Car> does not inherit from List<Vehicle> even though car inherits from vehicle. Likewise, DbSet<MlaPerson> does not inherit from DbSet<WebObject> even though MlaPerson inherits from WebObject.

What you need to do is something like this (I haven't tested this code):

protected void AddRelatedWebObject<A, B, O>(A mlaObject, B inputObject, List<Guid> guids) 
    where A : WebObject 
    where B : DbSet<O>
    where O : WebObject
{
    foreach (Guid guid in guids)
    {
        mlaObject.RelatedWebObjects.Add(inputObject.Find(guid));
        _db.SaveChanges();
    }
}

and use it thus:

foreach (ArticleRelationships item in articleRelationships)
{
    MlaArticle article = new MlaArticle();
    article = _db.MlaArticles.Include(m => m.WebSite).Where(m => m.Id == item.ArticleId).First();
    AddRelatedWebObject<MlaArticle, DbSet<MlaPerson>, MlaPerson>(article, _db.MlaPersons, item.PersonIds);
}

If you do it this way, you may be able to forgo the type specification (<MlaArticle, DbSet<MlaPerson>, MlaPerson>) because it should infer it.

like image 106
Chris Shain Avatar answered Jan 27 '23 09:01

Chris Shain