2009-09-02 25 views
6

Tôi có một mô hình ở trên cùng của mô hình cơ sở dữ liệu của tôi và ánh xạ các đối tượng trong Kho lưu trữ của tôi.Làm thế nào để sử dụng các lớp nhà máy với LINQ cho sql?

Tuy nhiên, có vẻ như nó tạo sự khác biệt cho dù tôi "chọn mới" trực tiếp trong Người dùng của tôi hoặc "chọn nhà máy" như được triển khai bên dưới. Tôi nhận được lỗi khi chạy, rằng phương thức CreateFromDbModel không có bản dịch sang sql (System.NotSupportedException).

Có cách nào khác không? Tôi có thể sửa nó bằng cách nào đó được không?

Lý do muốn sử dụng phương pháp nhà máy là tôi có thể instanciate đối tượng ở nơi khác và muốn giữ 'mã lập bản đồ ở một nơi ...

Thanks cho bất kỳ ý kiến, Anders

public IQueryable<User> GetUsers(bool includeTeams) 
    { 
     return from u in _db.sc_Players 
       where (includeTeams || (!u.aspnet_User.sc_Player.IsTeam)) 
       select UserFactory2.CreateFromDbModel(u); 
    } 


    public static User CreateFromDbModel(sc_Player player) 
    { 
     return new User 
        { 
         Id = player.sc_PlayerID, 
         FirstName = player.FirstName.Trim(), 
         LastName = player.LastName.Trim(), 
         PresentationName = player.FirstName.Trim() + " " + player.LastName.Trim(), 
         LoginName = player.aspnet_User.LoweredUserName, 
         IsTeam = player.IsTeam, 
         Email = player.aspnet_User.aspnet_Membership.Email, 
         Password = player.aspnet_User.aspnet_Membership.Password 
        }; 
    } 

Trả lời

1

Có phải vấn đề là do bạn đang trả về IQueryable trong phương thức GetUsers của bạn? Thay vào đó, hãy thử trả lại Danh sách. Điều này sẽ buộc truy vấn LINQ thực hiện trong phương thức.

public List<User> GetUsers(bool includeTeams) 
{ 
    return (from u in _db.sc_Players 
    where (includeTeams || (!u.aspnet_User.sc_Player.IsTeam)) 
    select UserFactory2.CreateFromDbModel(u)).ToList(); 
} 

Không chắc chắn nếu điều này sẽ khắc phục được sự cố, chỉ cần linh cảm. Tôi đã có thể lặp lại những gì bạn đang làm trong Linqpad trên một cơ sở dữ liệu địa phương, và nó đã làm việc. Nhưng mẫu của tôi không trả lại một IQueryable. Bạn có furthur modifing bộ sưu tập IQueryable bên ngoài GetUsers()?

Edit:

tôi đã thực hiện một số chi tiết kiểm tra. Tôi đã có thể lặp lại trong các lỗi chỉ khi tôi sửa đổi mẫu của tôi vì vậy bộ sưu tập IQueryable đã được sử dụng trong một truy vấn LINQ thứ hai sau khi gọi GetUsers():

IQueryable<User> query = GetUsers(true); 

var q = from u in query 
    where u.Name.Contains("Bob") 
    select new {Name = u.FirstName + " " + u.LastName}; 

Tôi đặt cược nếu bạn sẽ trả lại một danh sách như đề xuất trên trong GetUsers() lỗi sẽ biến mất. Mặt chỉ xuống là bất kỳ bộ lọc nào bạn thực hiện sau khi gọi GetUsers() sẽ không giới hạn lượng dữ liệu được trả về từ cơ sở dữ liệu vì bạn đã thực hiện truy vấn khi gọi .ToList().

Chỉnh sửa 2:

Đáng tiếc là tôi không nghĩ rằng có bất kỳ cách nào khác để bao gồm phương pháp nhà máy của bạn trong truy vấn. Tôi có thêm một ý tưởng nữa. Bạn có thể tạo một phương thức mở rộng cho IQueryable, gọi nó là một cái gì đó như ToUserList(). Bên trong ToUserList() bạn gọi ToList() trên truy vấn và phương thức factory của bạn trả về một tập hợp người dùng. Gọi phương thức này khi bạn kết thúc lọc dữ liệu bằng cách sử dụng LINQ. Điều này sẽ cho phép bạn chỉ thực hiện truy vấn khi bạn đã sẵn sàng tải dữ liệu từ cơ sở dữ liệu. Một ví dụ được đưa ra dưới đây.

public static List<Users> ToUserList(this IQueryable<User> query) 
{ 
    return query.ToList().Select(u => UserFactory2.CreateFromDbModel(u)); 
} 

Gọi phương pháp khuyến nông như thế này:

// Filter the data using linq. When you are ready to execute the query call: 
query.ToUserList(); // Query will execute and a list of User objects returned. 

Hy vọng điều này có ý nghĩa. Douglas H.

+0

Cảm ơn Douglas và Rossisdead, tôi đã thử chuyển đổi vào danh sách trước khi gọi phương pháp nhà máy của tôi, nhưng không chỉ làm tôi phải trả lại tất cả các LINQ các đối tượng từ cơ sở dữ liệu, tôi cũng phải xây dựng tất cả các đối tượng mô hình miền của mình - và tôi đang cố gắng tìm cách không yêu cầu ... Hơn nữa, tôi thực hiện lọc trong lớp dịch vụ của mình và sẽ phải chuyển đổi danh sách trở lại có thể truy vấn. ... –

+0

Hi Anders, Xem Chỉnh sửa 2 ở trên. – Douglas

+0

Hi Douglas, Tôi đánh dấu câu trả lời của bạn là câu trả lời, nhưng tôi hy vọng sẽ giữ cho các đối tượng linq cơ sở dữ liệu trong lớp dữ liệu, nơi gợi ý của bạn sẽ trưng ra các đối tượng lớp dữ liệu cho lớp dịch vụ. –

1

Lỗi khá nhiều giải thích tất cả.

"phương thức CreateFromDbModel không có bản dịch sang sql (Hệ thống.NotSupportedException) "

Phương thức CreateFromDbModel của bạn không phải là một hàm sql. Ứng dụng của bạn sẽ không thể chạy chức năng CreateFromDbModel cho đến khi các đối tượng đặc biệt được trả lại cho bạn từ máy chủ. ToList() hoặc một cái gì đó tương tự như trên truy vấn của bạn trước khi bạn có thể chạy CreateFromDbModel trên chúng.

Các vấn đề liên quan