2017-06-16 109 views
2

我得到了两个使用相同接口的实体。我想从实体框架两个结果我得到合并的IKurs一个列表:投射和合并两个相同接口但不同类型的列表

public async Task<IEnumerable<IKurs<ITeacherToCourse<IAdditionalTeacherData>, IAdditionalTeacherData>>> GetCourses(bool takeXtr) 
{ 
    IEnumerable<IKurs<ITeacherToCourse<IAdditionalTeacherData>, IAdditionalTeacherData>> result = new List<IKurs<ITeacherToCourse<IAdditionalTeacherData>, IAdditionalTeacherData>>(); 
    if (takeXtr) 
     using (var context = new Context()) 
     { 
      var courses = context.XtrCourses.Include(x=>x.TeachersToCourses).Where(_someCourseFilterForAgs); 
      result.Concat(await courses.ToListAsync()).Cast<IKurs<ITeacherToCourse<IAdditionalTeacherData>, IAdditionalTeacherData>>(); 
     } 

    using (var context = new Context()) 
    { 
     var courses = context.AgsCourses.Include(x=>x.TeachersToCourses).Where(_someCourseFilterForAgs); 
     result.Concat(await courses.ToListAsync()).Cast<IKurs<ITeacherToCourse<IAdditionalTeacherData>, IAdditionalTeacherData>>(); 
    } 
    return result; 
} 

正如你所看到的,我试着用 .Cast<IKurs<ITeacherToCourse<IAdditionalTeacherData>, IAdditionalTeacherData>>()铸造他们两个(即引发InvalidCastException)

这些都是我的Course类,既实现IKurs<T1<T2>, T1>但它们的T1和T2是不同的(但是仍然它们使用相同的接口):

public class XtrCourse : Core_Xtr_Course, IKurs<XtrTeacherToCourse, XtrAdditionalTeacherData> 
{ 
    public int Nr { get; set; } 
    // properties 

    public ICollection<XtrTeacherToCourse> TeachersToCourses { get; set; } 
} 

public class AgsCourse : Core_Ags_Course, IKurs<AgsTeacherToCourse, AgsAdditionalTeacherData> 
{ 
    public int Nr { get; set; } 
    // properties 

    public ICollection<AgsTeacherToCourse> TeachersToCourses { get; set; } 
} 

public interface IKurs<TTeacherToCourse, TAdditionalTeacherData> 
     where TTeacherToCourse : ITeacherToCourse<TAdditionalTeacherData> 
     where TAdditionalTeacherData: IAdditionalTeacherData 
{ 
    int Nr { get; set; } 

    ICollection<TTeacherToCourse> TeachersToCourses { get; set; } 
} 

public interface ITeacherToCourse<T> where T : IAdditionalTeacherData 
{ 
    int Nr { get; set; } 
    T AdditionalTeacherData { get; set; } 
} 

public interface IAdditionalTeacherData 
{ 
    // properties 
} 

AgsTeacherToCourseXtrTeacherToCourse都实现ITeacherToCourseAgsTeacherToCourseXtrTeacherToCourse都实现ITeacherToCourse

我怎样才能将它们合并到一个列表?

实际上,两个课程列表都来自不同的环境。这就是为什么我在GetCourses()两次启动上下文。

回答

1

一个主要的问题是

interface ITeacherToCourse<T> where T : IAdditionalTeacherData 
{ 
    int Nr { get; set; } 
    T AdditionalTeacherData { get; set; } 
} 

class XtrTeacherToCourse : ITeacherToCourse<XtrAdditionalTeacherData> 
{ 
    public int Nr { get; set; } 
    public XtrAdditionalTeacherData AdditionalTeacherData { get; set; } 
} 

class AgsTeacherToCourse : ITeacherToCourse<AgsAdditionalTeacherData> 
{ 
    public int Nr { get; set; } 
    public AgsAdditionalTeacherData AdditionalTeacherData { get; set; } 
} 

接口定义的合同,你只能设置一个值XtrAdditionalTeacherData类型的AdditionalTeacherDataXtrAdditionalTeacherDataAgsAdditionalTeacherDataAgsTeacherToCourse

我们怎样才能保证这个合同的时候,我们能够

ITeacherToCourse<IAdditionalTeacherData> ttc = new XtrTeacherToCourse(); 
ttc.AdditionalTeacherData = new AgsAdditionalTeacherData(); 

如果你不想设置AdditionalTeacherData属性,那么你可以声明接口一样

interface ITeacherToCourse<out T> where T : IAdditionalTeacherData 
{ 
    int Nr { get; set; } 
    T AdditionalTeacherData { get; } 
} 

AdditionalTeacherData是现在只读Tout T

现在我们能够

ITeacherToCourse<IAdditionalTeacherData> ttc; 
ttc = new XtrTeacherToCourse(); 
ttc = new AgsTeacherToCourse(); 

有了它相同的集合。

总接口声明

interface IAdditionalTeacherData 
{ 

} 

interface ITeacherToCourse<out T> where T : IAdditionalTeacherData 
{ 
    int Nr { get; set; } 
    T AdditionalTeacherData { get; } 
} 

interface IKurs<out TTeacherToCourse, out TAdditionalTeacherData> 
    where TTeacherToCourse : ITeacherToCourse<TAdditionalTeacherData> 
    where TAdditionalTeacherData : IAdditionalTeacherData 
{ 
    int Nr { get; set; } 
    IEnumerable<TTeacherToCourse> TeachersToCourses { get; } 
} 

和实现类

class XtrAdditionalTeacherData : IAdditionalTeacherData 
{ 

} 

class XtrTeacherToCourse : ITeacherToCourse<XtrAdditionalTeacherData> 
{ 
    public int Nr { get; set; } 
    public XtrAdditionalTeacherData AdditionalTeacherData { get; set; } 
} 

class XtrCourse : IKurs<XtrTeacherToCourse, XtrAdditionalTeacherData> 
{ 
    public int Nr { get; set; } 
    public ICollection<XtrTeacherToCourse> TeachersToCourses { get; set; } 
    // explicit implementation 
    IEnumerable<XtrTeacherToCourse> IKurs<XtrTeacherToCourse, XtrAdditionalTeacherData>.TeachersToCourses => TeachersToCourses; 
} 

class AgsAdditionalTeacherData : IAdditionalTeacherData 
{ 

} 

class AgsTeacherToCourse : ITeacherToCourse<AgsAdditionalTeacherData> 
{ 
    public int Nr { get; set; } 
    public AgsAdditionalTeacherData AdditionalTeacherData { get; set; } 
} 

class AgsCourse : IKurs<AgsTeacherToCourse, AgsAdditionalTeacherData> 
{ 
    public int Nr { get; set; } 
    public ICollection<AgsTeacherToCourse> TeachersToCourses { get; set; } 
    // explicit implementation 
    IEnumerable<AgsTeacherToCourse> IKurs<AgsTeacherToCourse, AgsAdditionalTeacherData>.TeachersToCourses => TeachersToCourses; 
} 

,现在我们可以在没有任何投

var collection = new List<IKurs<ITeacherToCourse<IAdditionalTeacherData>, IAdditionalTeacherData>>(); 

collection.Add(new XtrCourse()); 
collection.Add(new AgsCourse()); 
+0

哇。完善。 'out'正是问题所在。 Thx帮助:) –

1

无需铸造,您可以添加任何IKurs<ITeacherToCourse<IAdditionalTeacherData>, IAdditionalTeacherData>到您的清单。

interface IMyclass{} 

    class MyType1 : IMyclass {} 

    class MyType2 : IMyclass {} 

    public class SomeClass 
    { 
     private List<IMyclass> MyList = new List<IMyclass>(); 

     public void DoSomething() 
     { 
      MyList.AddRange(new List<IMyclass> { new MyType1(), new MyType1() }); 
      MyList.AddRange(new List<IMyclass> { new MyType2(), new MyType2() }); 
     } 
    } 
+0

试着用'result.AddRange添加实例(AWAIT courses.ToListAsync());'但这让我的编译器哭:(:(参数类型列表不是ssignable to parametertype IEnumerable ,IAdditionalTeacherData >>' - 我想我首先需要投射整个结构呢? –

+0

@MatthiasBurger的东西必须与您的类型。我不得不承认我对你复杂的类型定义感到困惑,但只要你从你的编译器得到这个错误,转换就不能工作。该错误基本上告诉你,铸造将无法正常工作。 – oerkelens

+0

我仍然不完全知道为什么,但Rufo爵士已经发现了这个问题。我需要研究为什么我需要在这里的界面中使用'out'。但thx为你的帮助:) - 是的,结构混乱。你是对的 - 这不是我的数据库设计:D –

相关问题