LINQ to SQL:如何创建条件包含的东西?

时间:2015-06-18 17:10:37

标签: .net linq entity-framework include conditional-statements

我想创建一个包含User的查询,其实体Eventtype == 1。我还想将Event个条目加载到EventsCollection中。我的代码类似于.Include(u => u.EventsCollection),但这只会加载所有Event条目 - 我只想加载类型== 1。

我有这样的简单模型:

public class User
{
    public int UserId { get; set; }

    public ICollection<Event> EventsCollection { get; set; }
}
public class Event
{
    public int EventId { get; set; }
    public int UserId { get; set; }
    public int Type { get; set; }

    public User User {get; set; }
}

有什么想法吗?

编辑:

最后我找到了解决方案: 我们需要新的DataContext对象,之前已经加载了没有事件实体。

然后我们需要像这样过滤事件:

var filteredEventsCollection = db.Events
    .Where(ev => ev.Type == 1)
    .ToList(); //Materialize query here

现在我们应该像这样查询用户:

var usersWithFilteredEvents = db.Users
    .Where(u => u.EventsCollection.Any(ev => ev.Type == 1))
    .ToList();

就是这样! EF将使用来自第一个查询的数据替换EventsCollection。

3 个答案:

答案 0 :(得分:1)

你不能使用var result = (from u in db.Users where u.EventsCollection.Any(ev => ev.Type == 1) select new { User = u, Events = u.EventsCollection.Where(ev => ev.Type == 1), }).ToList() // materialize query here! .Select(uev => uev.User) .ToList(); 并过滤哪些实体被急切加载(或延迟加载),但你可以通过使用投影伪造它:

EventCollection
  • 这应该返回一个IEnumerable,其中包含您想要的事件Event
  • 如果先前已将其他User.EventsCollection个实体加载到上下文中,则无效!
  • 还必须为virtual删除延迟加载,方法是删除toggleButton - 您已经完成的操作 - 或者在整个上下文中禁用它。
  • 请参阅this link

无论如何,我可能只是直接使用投影,因为那样更安全。

答案 1 :(得分:0)

这将为您提供所需内容:

void Main(){

List<User> users = new List<User>{
 new User{ UserId=1},
 new User{ UserId=2}
};

List<Event> events = new List<Event>{
    new Event{ EventId=1, UserId=2, Type=0},
    new Event{ EventId=2, UserId=2, Type=1},
    new Event{ EventId=4, UserId=2, Type=1},
    new Event{ EventId=5, UserId=2, Type=0},
    new Event{ EventId=1, UserId=1, Type=1},
    new Event{ EventId=2, UserId=1, Type=0},
    new Event{ EventId=4, UserId=1, Type=0},
    new Event{ EventId=5, UserId=1, Type=1},
};



var result = users.GroupJoin(events.Where (e =>e.Type==1 ),
    u => u.UserId,
    e => e.UserId,
    (a, b) => new {a.UserId,b});    
//result.Dump();

}

 // Define other methods and classes here
public class User
{
  public int UserId { get; set; }

  public ICollection<Event> EventsCollection { get; set; }
}
public class Event
{
  public int EventId { get; set; }
  public int UserId { get; set; }
  public int Type { get; set; }

  public User User {get; set; }
}

答案 2 :(得分:-2)

如果您只是尝试获取userID == 1的事件,则可以使用以下内容。这将只为您提供用户的事件收集所需的事件。

        User u = new User()
        {
            UserId = 60
        };

        Event e1 = new Event() { EventId = 1, UserId = 2, Type = 3, User = u };
        Event e2 = new Event() { EventId = 2, UserId = 3, Type = 4, User = u };
        Event e3 = new Event() { EventId = 3, UserId = 4, Type = 5, User = u };
        Event e_Test = new Event() { EventId = 7, UserId = 1, Type = 5, User = u };

        u.EventsCollection = new List<Event>();

        u.EventsCollection.Add(e1);
        u.EventsCollection.Add(e2); 
        u.EventsCollection.Add(e3);
        u.EventsCollection.Add(e_Test);


        var h = from use in u.EventsCollection where use.UserId == 1 select use;