Tôi biết câu hỏi này đã được hỏi nhưng tôi không thể tìm thấy câu trả lời thỏa mãn tôi. Những gì tôi đang cố gắng làm là lấy một số DbSet<T>
cụ thể dựa trên tên loại của nó.Tìm DbSet chung trong DbContext động
tôi có như sau:
[assembly: System.Runtime.CompilerServices.InternalsVisibleTo("MyDllAssemblyName")]
[assembly: System.Runtime.CompilerServices.InternalsVisibleTo("MyCallingAssemblyName")]
class MyDbContext : DbContext {
public DbSet<ModelA> A { get; set; }
public DbSet<ModelB> B { get; set; }
public dynamic GetByName_SwitchTest(string name) {
switch (name) {
case "A": return A;
case "B": return B;
}
}
public dynamic GetByName_ReflectionTest(string fullname)
{
Type targetType = Type.GetType(fullname);
var model = GetType()
.GetRuntimeProperties()
.Where(o =>
o.PropertyType.IsGenericType &&
o.PropertyType.GetGenericTypeDefinition() == typeof(DbSet<>) &&
o.PropertyType.GenericTypeArguments.Contains(targetType))
.FirstOrDefault();
if (null != model)
return model.GetValue(this);
return null;
}
}
Tôi không có sự cố khi nhận kiểu riêng của mình cho dù đó là thông qua một công tắc đơn giản hoặc phản ánh. Tuy nhiên, tôi cần phải trả về kiểu như là một động vì tôi không biết loại DbSet sẽ là gì. Sau đó, ở một nơi khác trong cùng một assembly, tôi sử dụng nó theo cách này:
// MyDbContext MyDbContextInstance..
var model = MyDbContextInstance.GetByName_SwitchTest("A");
var record1 = model.FirstOrDefault(); // It crashes here with RunTimeBinderException
Tại thời điểm này model
chứa một thể hiện của một loại InternalDbSet<ModelA>
. Từ đó, bất kỳ sử dụng tôi làm với các đối tượng model
tôi nhận được một RunTimeBinderException: 'Microsoft.Data.Entity.Internal.InternalDbSet' không chứa một định nghĩa cho 'FirstOrDefault'
tra trên trang web, tôi tìm thấy một blog post giải thích rằng (dixit blog của mình):
lý do cuộc gọi đến FirstOrDefault() không thành công là loại thông tin không có sẵn khi chạy. Lý do không phải là là do các loại ẩn danh không được công khai. Khi phương thức trả về một thể hiện của loại ẩn danh đó, nó trả về một System.Object tham chiếu một cá thể của một loại ẩn danh - một loại mà thông tin của chúng không có sẵn cho chương trình chính.
Và sau đó ông chỉ là một giải pháp:
Các giải pháp thực sự là khá đơn giản. Tất cả chúng ta phải làm là mở ra AssemplyInfo.cs của dự án ClassLibrary1 và thêm dòng sau vào nó:
[assembly:InternalsVisibleTo("assembly-name")]
tôi đã thử giải pháp này trên mã của tôi, nhưng nó không hoạt động. Đối với thông tin tôi có một giải pháp asp.net 5 với hai hội đồng chạy trên dnx dotnet46. Một ứng dụng và một dll chứa tất cả các mô hình của tôi và DbContext. Tất cả các cuộc gọi liên quan tôi làm được đặt trên dll mặc dù.
Giải pháp này có cơ hội hoạt động không? Tôi có thiếu gì đó không? Bất kỳ con trỏ nào sẽ được đánh giá cao?
Cảm ơn trước
[EDIT]
Tôi đã cố gắng để trở IQueryable<dynamic>
hơn dynamic
và tôi có thể làm các truy vấn cơ bản model.FirstOrDefault();
nhưng trên hết tôi muốn để có thể lọc trên một trường quá:
var record = model.FirstOrDefault(item => item.MyProperty == true);
thế nào về sự thay đổi năng động để IEnumerable? –
Kelmen
Tôi đã thử một cái gì đó tương tự (thay đổi để IQueryable) và mặc dù tôi có thể làm một số truy vấn như 'model.FirstOrDefault()' nó sẽ không cho phép tôi làm những việc như 'model.FirstOrDefault (item => item.MyProperty = = true) '. làm giảm tính hữu dụng của sự vật. –
DarkUrse
Tôi đã gặp phải sự cố tương tự này. Bất kỳ cơ hội nào bạn đã đạt đến độ phân giải? – JosephGarrone