如何使用通用存储库模式的连接 - 实体框架

时间:2017-03-11 09:04:05

标签: c# entity-framework repository-pattern unit-of-work

我在public class FetchData2 { public static Connection getConnection() { System.out.println("initial connection "+connection); // DB Connection Connection connection = null; try { System.out.println("i am inside connection"); Class.forName("oracle.jdbc.driver.OracleDriver"); connection = DriverManager.getConnection("connection"); System.out.println("Connection estabilished"+connection); } catch (Exception e) { System.out.println("Connection error1: "+e); } return connection; } } public static ArrayList<Elements2> getAllElements2 (String sino,String irepno) { ArrayList<Elements2> itemListinsp = new ArrayList<Elements2>(); try (Connection connection = FetchData2.getConnection(); Statement statement1 = connection.createStatement(); ResultSet rs = statement1.executeQuery("query1")) { while(rs.next()) { Elements2 iteminsp = new Elements2(); iteminsp.setParameters(rs.getString("parameters")); iteminsp.setSpecifications(rs.getString("specifications")); iteminsp.setActual1(rs.getString("actual1")); iteminsp.setActual2(rs.getString("actual2")); iteminsp.setActual3(rs.getString("actual3")); iteminsp.setActual4(rs.getString("actual4")); iteminsp.setActual5(rs.getString("actual5")); itemListinsp.add(iteminsp); } } catch (Exception e) { System.out.println("Connection query exection error: "+e); } return itemListinsp; } public static ArrayList<Elements2> getcritElements2(String icode) { System.out.println("I AM IN SECOND FETCH"); ArrayList<Elements2> listcrit = new ArrayList<Elements2>(); System.out.println("incoming icode: "+icode); try (Connection connection = FetchData2.getConnection(); Statement statementinsp = connection.createStatement(); ResultSet rsinsp = statementinsp.executeQuery("query2")) { if (!rsinsp.isBeforeFirst() ) { System.out.println("no data"); } while(rsinsp.next()) { Elements2 inspcrit=new Elements2(); inspcrit.setParameters(rsinsp.getString("parameters")); inspcrit.setSpecifications(rsinsp.getString("specifications")); listcrit.add(inspcrit); } } catch (Exception e) { System.out.println("Connection query exection error: "+e); } System.out.println(listcrit.size()); System.out.println(listcrit.get(0).getParameters()); System.out.println(listcrit.get(0).getSpecifications()); return listcrit; } 之下处理我的Generic Repository,对于一个易于使用的单个实体,当我尝试加入CRUD时会出现问题。

假设我有这些POCO,它们使用流畅的api(多对多和一对多关系)进行映射:

POCOs

映射:

public class Student
{
    public Student() 
    {
        this.Courses = new HashSet<Course>();
    }

    public int StudentId { get; set; }
    public string StudentName { get; set; }

    //FKs 
    public virtual Standard Standard { get; set; }
    public int StdandardRefId { get; set; }

    public virtual ICollection<Course> Courses { get; set; }
}

public class Course
{
    public Course()
    {
        this.Students = new HashSet<Student>();
    }

    public int CourseId { get; set; }
    public string CourseName { get; set; }

    public virtual ICollection<Student> Students { get; set; }
}
public class Standard
{
    public Standard()
    {
        Students = new List<Student>();
    }
    public int StandardId { get; set; }
    public string Description { get; set; }

    public virtual ICollection<Student> Students { get; set; }
}

通用存储库:

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    //Many-To-Many
    modelBuilder.Entity<Student>()
                .HasMany<Course>(s => s.Courses)
                .WithMany(c => c.Students)
                .Map(cs =>
                        {
                            cs.MapLeftKey("StudentRefId");
                            cs.MapRightKey("CourseRefId");
                            cs.ToTable("StudentCourse");
                        });
        //One-To-Many
        modelBuilder.Entity<Student>()
                .HasRequired<Standard>(s => s.Standard)
                .WithMany(s => s.Students)
                .HasForeignKey(s => s.StandardId);

}

现在,如果我想加入Standard to Many-to-Many Table,我怎么能够做到这一点?

2 个答案:

答案 0 :(得分:12)

因此,基于您的编辑,我假设您想加入学生和标准。

您要做的第一件事是更改存储库,以便它不会实例化上下文。您应该将其作为参数传递并存储对它的引用:

public Repository(MyDbContext myCtx)
{
    context = myCtx;
    this.dbSet = context.Set<T>();
}

您要做的第二件事是更改您的存储库以更改GetAll()方法以返回IQueryable<T>而不是ICollection<T>

然后更改GetAll()的实施:

return dbSet;

这样您只能获得查询而不是所有实体的评估列表。然后你可以使用存储库的GetAll()方法进行连接,就像使用数据库集一样:

using (MyDbContext ctx = new MyDbContext())
{
  var studentRep = new Repository<Student>(ctx);
  var standardRep = new Repository<Standard>(ctx);
  var studentToStandard = studentRep.GetAll().Join(standardRep.GetAll(), 
                        student => student.StandardRefId,
                        standard => standard.StandardId,
                        (stud, stand) => new { Student=stud, Standard=stand }).ToList();
}

通过此操作,您会在IQueryable<T>中获得studentToStandard,一旦您在其上调用ToList(),该push将在数据库中运行。请注意,您必须将相同的上下文传递给两个存储库才能使其正常工作。

我建议您查看工作单元设计模式。在处理多个存储库时,它会有很大帮助。

https://docs.microsoft.com/en-us/aspnet/mvc/overview/older-versions/getting-started-with-ef-5-using-mvc-4/implementing-the-repository-and-unit-of-work-patterns-in-an-asp-net-mvc-application

当涉及多个实体集时,这是一种更有条理,更易于维护的处理事务的方式,并促进更好地分离关注点。

希望我能正确理解你的问题,这有帮助。

答案 1 :(得分:0)

我在使用实体框架的地方进行了此查询

var result = (from metattachType in _dbContext.METATTACH_TYPE
                join lineItemMetattachType in _dbContext.LINE_ITEM_METATTACH_TYPE on metattachType.ID equals lineItemMetattachType.METATTACH_TYPE_ID
                where (lineItemMetattachType.LINE_ITEM_ID == lineItemId && lineItemMetattachType.IS_DELETED == false
                && metattachType.IS_DELETED == false)
                select new MetattachTypeDto()
                {
                    Id = metattachType.ID,
                    Name = metattachType.NAME
                }).ToList();

并将其更改为我使用存储库模式的位置 Linq

            return await _attachmentTypeRepository.GetAll().Where(x => !x.IsDeleted)
                .Join(_lineItemAttachmentTypeRepository.GetAll().Where(x => x.LineItemId == lineItemId && !x.IsDeleted),
                attachmentType => attachmentType.Id,
                lineItemAttachmentType => lineItemAttachmentType.MetattachTypeId,
                (attachmentType, lineItemAttachmentType) => new AttachmentTypeDto
                {
                    Id = attachmentType.Id,
                    Name = attachmentType.Name
                }).ToListAsync().ConfigureAwait(false);

Linq-to-sql

            return (from attachmentType in _attachmentTypeRepository.GetAll()
                    join lineItemAttachmentType in _lineItemAttachmentTypeRepository.GetAll() on attachmentType.Id equals lineItemAttachmentType.MetattachTypeId
                    where (lineItemAttachmentType.LineItemId == lineItemId && !lineItemAttachmentType.IsDeleted && !attachmentType.IsDeleted)
                    select new AttachmentTypeDto()
                    {
                        Id = attachmentType.Id,
                        Name = attachmentType.Name
                    }).ToList();

另外,请注意,Linq-to-Sql比Linq快14倍...

enter image description here