C # Output Type - Error - There is no implicit link conversion from

I have a method that iterates over a list of commands and saves them to a database via DbContext. B is a collection of WebObjects DbSet objects (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(); } } 

Using

 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 calling B was a DbSet<WebObject> would work because the MlaPerson base class is WebObject, but I'm wrong. I get an error message:

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 help offered. Thank you for your help. IN

+4
source share
3 answers

You make a generic generic mistake - assuming collections are covariant. That is, an instance of List<Car> does not inherit from List<Vehicle> , even if a car is inherited from a vehicle. Similarly, DbSet<MlaPerson> does not inherit from DbSet<WebObject> , although MlaPerson inherits from WebObject.

What you need to do is something like this (I have not 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 this way:

 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 can discard the type specification ( <MlaArticle, DbSet<MlaPerson>, MlaPerson> ) because this should output it.

+8
source

A DbSet<MlaPerson> not a DbSet<WebObject> just because MlaPerson comes from WebObject . Find โ€œtotal varianceโ€ in the stack overflow to find many reasons.

You might want to change the parameters and limitations of the method as follows:

 protected void AddRelatedWebObject<A, B>(A mlaObject, DbSet<B> inputObject, List<Guid> guids) where A : WebObject where B : WebObject 

And then name it like this:

 AddRelatedWebObject<MlaArticle, MlaPerson>(article, _db.MlaPersons, item.PersonIds); 

This may work - perhaps it even works with the output type to allow this:

 AddRelatedWebObject(article, _db.MlaPersons, item.PersonIds); 

I would also suggest that you rename your type parameters to something like TSource and TTarget , in order to be more clear and follow the rules.

+7
source

- EDIT - THIS RESPONSE IS WRONG. SEE COMMENTS FOR MORE INFORMATION -

Upcasting does not work with containers (unless you are raising the data structure, but it is not). Imagine the following code (written using arrays for simplicity, but the same principles apply to all common containers):

 class A{} class B:A{} /*Inside a method*/ B[] arrayB=new B[10]; A[] arrayA=arrayB;//This line will produce a compile error arrayA[0]=new A(); 

arrayB[0] contains an object of type A, although A not a derived class of B This is why performance improvements do not work for containers.

0
source

All Articles